FV Flowplayer Video Player - Version 7.5.21.727

Version Description

  • 2022/04/07 =

  • Bugfix - Position saving - issues with position restore when multiple players on the page

  • Bugfix - CSS - ensure the controlbar fonts load before video starts playing

  • Bugfix - LearnDash LMS support - fix FV Player Pro video ads to not affect lesson completion button

Download this release

Release Info

Developer FolioVision
Plugin Icon 128x128 FV Flowplayer Video Player
Version 7.5.21.727
Comparing to
See all releases

Code changes from version 7.5.15.727 to 7.5.21.727

Files changed (51) hide show
  1. controller/editor.php +7 -0
  2. controller/frontend.php +3 -2
  3. css/admin.css +8 -7
  4. css/flowplayer.css +87 -58
  5. css/fonts/fpicons.svg +2 -2
  6. css/fvp-icon-sprite.svg +1 -1
  7. css/icons/flowplayer.svg +2 -2
  8. css/img/no-play-white.svg +2 -2
  9. css/shortcode-editor.css +41 -1
  10. css/sitemap-index.xsl +1 -1
  11. flowplayer.php +7 -6
  12. flowplayer/flowplayer.dashjs.min.js +1 -1
  13. flowplayer/fv-player-loader.babel.js +5 -5
  14. flowplayer/fv-player-loader.dev.js +5 -5
  15. flowplayer/fv-player.min.js +1 -1
  16. flowplayer/modules/appearance.module.js +6 -0
  17. flowplayer/modules/compatibility.module.js +11 -0
  18. flowplayer/modules/fv-player.js +31 -5
  19. flowplayer/modules/hls-live-check.module.js +1 -1
  20. flowplayer/modules/learndash.module.js +4 -0
  21. flowplayer/modules/mobile.module.js +3 -3
  22. flowplayer/modules/multiple-playback.module.js +4 -0
  23. flowplayer/modules/old-browsers.module.js +9 -9
  24. flowplayer/modules/playback-position.module.js +73 -15
  25. flowplayer/modules/playlist-repeat.module.js +4 -3
  26. flowplayer/modules/playlist-start-position.module.js +5 -1
  27. flowplayer/modules/sticky.module.js +41 -25
  28. flowplayer/modules/volume.module.js +6 -1
  29. includes/mailchimp-api/composer.json +0 -28
  30. js/admin-convertor.js +26 -9
  31. js/editor-screenshots.js +24 -22
  32. js/media-library-browser-base.js +2 -2
  33. js/shortcode-editor.js +235 -109
  34. models/checker.php +11 -8
  35. models/conversion.php +1 -1
  36. models/conversion/conversion-base.class.php +19 -9
  37. models/conversion/shortcode2DB.class.php +315 -112
  38. models/db-player.php +56 -212
  39. models/db-video-meta.php +13 -0
  40. models/db-video.php +5 -11
  41. models/db.php +343 -102
  42. models/flowplayer-frontend.php +12 -8
  43. models/flowplayer.php +49 -6
  44. models/learndash.php +14 -0
  45. models/lightbox.php +1 -1
  46. models/list-table.php +8 -5
  47. models/player-position-save.php +39 -5
  48. models/video-encoder/video-encoder.php +31 -12
  49. readme.txt +33 -0
  50. uninstall.php +3 -0
  51. view/admin.php +25 -22
controller/editor.php CHANGED
@@ -471,3 +471,10 @@ Elementor support
471
  add_action( 'elementor/editor/wp_head', 'fv_player_shortcode_editor_scripts_enqueue' );
472
  add_action( 'elementor/editor/wp_head', 'fv_wp_flowplayer_edit_form_after_editor' );
473
  add_action( 'elementor/editor/wp_head', 'flowplayer_prepare_scripts' );
 
 
 
 
 
 
 
471
  add_action( 'elementor/editor/wp_head', 'fv_player_shortcode_editor_scripts_enqueue' );
472
  add_action( 'elementor/editor/wp_head', 'fv_wp_flowplayer_edit_form_after_editor' );
473
  add_action( 'elementor/editor/wp_head', 'flowplayer_prepare_scripts' );
474
+
475
+ // Bring back the FV Player into Elementor Elements search - it's their "Hide native WordPress widgets from search results" setting
476
+ add_filter( 'pre_option_elementor_experiment-e_hidden_wordpress_widgets', 'fv_player_editor_elementor_widget_search_enable' );
477
+
478
+ function fv_player_editor_elementor_widget_search_enable( $val ) {
479
+ return 'inactive';
480
+ }
controller/frontend.php CHANGED
@@ -423,6 +423,7 @@ function flowplayer_prepare_scripts() {
423
  $aConf['sticky_video'] = $fv_fp->_get_option('sticky_video');
424
  $aConf['sticky_place'] = $fv_fp->_get_option('sticky_place');
425
  $aConf['sticky_width'] = $fv_fp->_get_option('sticky_width');
 
426
 
427
  global $post;
428
  if( $post && isset($post->ID) && $post->ID > 0 ) {
@@ -672,12 +673,12 @@ add_action( 'fv_player_extensions_admin_load_assets', 'fv_player_footer_svg_rewi
672
 
673
  function fv_player_footer_svg_rewind() {
674
  ?>
675
- <svg style="position: absolute; width: 0; height: 0; overflow: hidden;" class="fvp-icon" xmlns="http://www.w3.org/2000/svg">
676
  <g id="fvp-rewind">
677
  <path d="M22.7 10.9c0 1.7-0.4 3.3-1.1 4.8 -0.7 1.5-1.8 2.8-3.2 3.8 -0.4 0.3-1.3-0.9-0.9-1.2 1.2-0.9 2.1-2 2.7-3.3 0.7-1.3 1-2.7 1-4.1 0-2.6-0.9-4.7-2.7-6.5 -1.8-1.8-4-2.7-6.5-2.7 -2.5 0-4.7 0.9-6.5 2.7 -1.8 1.8-2.7 4-2.7 6.5 0 2.4 0.8 4.5 2.5 6.3 1.7 1.8 3.7 2.7 6.1 2.9l-1.2-2c-0.2-0.3 0.9-1 1.1-0.7l2.3 3.7c0.2 0.3 0 0.6-0.2 0.7L9.5 23.8c-0.3 0.2-0.9-0.9-0.5-1.2l2.1-1.1c-2.7-0.2-5-1.4-6.9-3.4 -1.9-2-2.8-4.5-2.8-7.2 0-3 1.1-5.5 3.1-7.6C6.5 1.2 9 0.2 12 0.2c3 0 5.5 1.1 7.6 3.1C21.7 5.4 22.7 7.9 22.7 10.9z" fill="#fff"/><path d="M8.1 15.1c-0.1 0-0.1 0-0.1-0.1V8C8 7.7 7.8 7.9 7.7 7.9L6.8 8.3C6.8 8.4 6.7 8.3 6.7 8.2L6.3 7.3C6.2 7.2 6.3 7.1 6.4 7.1l2.7-1.2c0.1 0 0.4 0 0.4 0.3v8.8c0 0.1 0 0.1-0.1 0.1H8.1z" fill="#fff"/><path d="M17.7 10.6c0 2.9-1.3 4.7-3.5 4.7 -2.2 0-3.5-1.8-3.5-4.7s1.3-4.7 3.5-4.7C16.4 5.9 17.7 7.7 17.7 10.6zM12.3 10.6c0 2.1 0.7 3.4 2 3.4 1.3 0 2-1.2 2-3.4 0-2.1-0.7-3.4-2-3.4C13 7.2 12.3 8.5 12.3 10.6z" fill="#fff"/>
678
  </g>
679
  </svg>
680
- <svg style="position: absolute; width: 0; height: 0; overflow: hidden;" class="fvp-icon" xmlns="http://www.w3.org/2000/svg">
681
  <g id="fvp-forward">
682
  <path d="M22.7 10.9c0 1.7-0.4 3.3-1.1 4.8 -0.7 1.5-1.8 2.8-3.2 3.8 -0.4 0.3-1.3-0.9-0.9-1.2 1.2-0.9 2.1-2 2.7-3.3 0.7-1.3 1-2.7 1-4.1 0-2.6-0.9-4.7-2.7-6.5 -1.8-1.8-4-2.7-6.5-2.7 -2.5 0-4.7 0.9-6.5 2.7 -1.8 1.8-2.7 4-2.7 6.5 0 2.4 0.8 4.5 2.5 6.3 1.7 1.8 3.7 2.7 6.1 2.9l-1.2-2c-0.2-0.3 0.9-1 1.1-0.7l2.3 3.7c0.2 0.3 0 0.6-0.2 0.7L9.5 23.8c-0.3 0.2-0.9-0.9-0.5-1.2l2.1-1.1c-2.7-0.2-5-1.4-6.9-3.4 -1.9-2-2.8-4.5-2.8-7.2 0-3 1.1-5.5 3.1-7.6C6.5 1.2 9 0.2 12 0.2c3 0 5.5 1.1 7.6 3.1C21.7 5.4 22.7 7.9 22.7 10.9z" fill="#fff" transform="scale(-1,1) translate(-24,0)" /><path d="M8.1 15.1c-0.1 0-0.1 0-0.1-0.1V8C8 7.7 7.8 7.9 7.7 7.9L6.8 8.3C6.8 8.4 6.7 8.3 6.7 8.2L6.3 7.3C6.2 7.2 6.3 7.1 6.4 7.1l2.7-1.2c0.1 0 0.4 0 0.4 0.3v8.8c0 0.1 0 0.1-0.1 0.1H8.1z" fill="#fff" /><path d="M17.7 10.6c0 2.9-1.3 4.7-3.5 4.7 -2.2 0-3.5-1.8-3.5-4.7s1.3-4.7 3.5-4.7C16.4 5.9 17.7 7.7 17.7 10.6zM12.3 10.6c0 2.1 0.7 3.4 2 3.4 1.3 0 2-1.2 2-3.4 0-2.1-0.7-3.4-2-3.4C13 7.2 12.3 8.5 12.3 10.6z" fill="#fff" />
683
  </g>
423
  $aConf['sticky_video'] = $fv_fp->_get_option('sticky_video');
424
  $aConf['sticky_place'] = $fv_fp->_get_option('sticky_place');
425
  $aConf['sticky_width'] = $fv_fp->_get_option('sticky_width');
426
+ $aConf['sticky_min_width'] = intval( apply_filters( 'fv_player_sticky_min_width', 1020 ) );
427
 
428
  global $post;
429
  if( $post && isset($post->ID) && $post->ID > 0 ) {
673
 
674
  function fv_player_footer_svg_rewind() {
675
  ?>
676
+ <svg style="position: absolute; width: 0; height: 0; overflow: hidden;" class="fvp-icon" xmlns="https://www.w3.org/2000/svg">
677
  <g id="fvp-rewind">
678
  <path d="M22.7 10.9c0 1.7-0.4 3.3-1.1 4.8 -0.7 1.5-1.8 2.8-3.2 3.8 -0.4 0.3-1.3-0.9-0.9-1.2 1.2-0.9 2.1-2 2.7-3.3 0.7-1.3 1-2.7 1-4.1 0-2.6-0.9-4.7-2.7-6.5 -1.8-1.8-4-2.7-6.5-2.7 -2.5 0-4.7 0.9-6.5 2.7 -1.8 1.8-2.7 4-2.7 6.5 0 2.4 0.8 4.5 2.5 6.3 1.7 1.8 3.7 2.7 6.1 2.9l-1.2-2c-0.2-0.3 0.9-1 1.1-0.7l2.3 3.7c0.2 0.3 0 0.6-0.2 0.7L9.5 23.8c-0.3 0.2-0.9-0.9-0.5-1.2l2.1-1.1c-2.7-0.2-5-1.4-6.9-3.4 -1.9-2-2.8-4.5-2.8-7.2 0-3 1.1-5.5 3.1-7.6C6.5 1.2 9 0.2 12 0.2c3 0 5.5 1.1 7.6 3.1C21.7 5.4 22.7 7.9 22.7 10.9z" fill="#fff"/><path d="M8.1 15.1c-0.1 0-0.1 0-0.1-0.1V8C8 7.7 7.8 7.9 7.7 7.9L6.8 8.3C6.8 8.4 6.7 8.3 6.7 8.2L6.3 7.3C6.2 7.2 6.3 7.1 6.4 7.1l2.7-1.2c0.1 0 0.4 0 0.4 0.3v8.8c0 0.1 0 0.1-0.1 0.1H8.1z" fill="#fff"/><path d="M17.7 10.6c0 2.9-1.3 4.7-3.5 4.7 -2.2 0-3.5-1.8-3.5-4.7s1.3-4.7 3.5-4.7C16.4 5.9 17.7 7.7 17.7 10.6zM12.3 10.6c0 2.1 0.7 3.4 2 3.4 1.3 0 2-1.2 2-3.4 0-2.1-0.7-3.4-2-3.4C13 7.2 12.3 8.5 12.3 10.6z" fill="#fff"/>
679
  </g>
680
  </svg>
681
+ <svg style="position: absolute; width: 0; height: 0; overflow: hidden;" class="fvp-icon" xmlns="https://www.w3.org/2000/svg">
682
  <g id="fvp-forward">
683
  <path d="M22.7 10.9c0 1.7-0.4 3.3-1.1 4.8 -0.7 1.5-1.8 2.8-3.2 3.8 -0.4 0.3-1.3-0.9-0.9-1.2 1.2-0.9 2.1-2 2.7-3.3 0.7-1.3 1-2.7 1-4.1 0-2.6-0.9-4.7-2.7-6.5 -1.8-1.8-4-2.7-6.5-2.7 -2.5 0-4.7 0.9-6.5 2.7 -1.8 1.8-2.7 4-2.7 6.5 0 2.4 0.8 4.5 2.5 6.3 1.7 1.8 3.7 2.7 6.1 2.9l-1.2-2c-0.2-0.3 0.9-1 1.1-0.7l2.3 3.7c0.2 0.3 0 0.6-0.2 0.7L9.5 23.8c-0.3 0.2-0.9-0.9-0.5-1.2l2.1-1.1c-2.7-0.2-5-1.4-6.9-3.4 -1.9-2-2.8-4.5-2.8-7.2 0-3 1.1-5.5 3.1-7.6C6.5 1.2 9 0.2 12 0.2c3 0 5.5 1.1 7.6 3.1C21.7 5.4 22.7 7.9 22.7 10.9z" fill="#fff" transform="scale(-1,1) translate(-24,0)" /><path d="M8.1 15.1c-0.1 0-0.1 0-0.1-0.1V8C8 7.7 7.8 7.9 7.7 7.9L6.8 8.3C6.8 8.4 6.7 8.3 6.7 8.2L6.3 7.3C6.2 7.2 6.3 7.1 6.4 7.1l2.7-1.2c0.1 0 0.4 0 0.4 0.3v8.8c0 0.1 0 0.1-0.1 0.1H8.1z" fill="#fff" /><path d="M17.7 10.6c0 2.9-1.3 4.7-3.5 4.7 -2.2 0-3.5-1.8-3.5-4.7s1.3-4.7 3.5-4.7C16.4 5.9 17.7 7.7 17.7 10.6zM12.3 10.6c0 2.1 0.7 3.4 2 3.4 1.3 0 2-1.2 2-3.4 0-2.1-0.7-3.4-2-3.4C13 7.2 12.3 8.5 12.3 10.6z" fill="#fff" />
684
  </g>
css/admin.css CHANGED
@@ -1,16 +1,17 @@
1
  #content .fv-player-video-checker, .fv-player-video-checker { pointer-events: none; position: absolute; top: 0; left: 0; z-index: 20; }
 
2
  #content .flowplayer .fv-player-video-checker small, .flowplayer .fv-player-video-checker small { pointer-events: auto; position:relative;left:15px;top:10px;-webkit-transition:all .15s 0s;-moz-transition:all .15s 0s;transition:all .15s 0s }
3
- #content .flowplayer.is-mouseover.is-ready .fv-player-video-checker small,
4
- .flowplayer.is-mouseover.is-ready .fv-player-video-checWker small,
5
- #content .flowplayer.is-ready.is-paused .fv-player-video-checker small,
6
- .flowplayer.is-ready.is-paused .fv-player-video-checker small { top: 3em }
7
  #content .flowplayer .fv-player-video-checker.is-open small,
8
  .flowplayer .fv-player-video-checker.is-open small,
9
  #content .flowplayer.has-video-checker .fv-player-video-checker.is-open small,
10
- .flowplayer.has-video-checker .fv-player-video-checker.is-open small { top:0;left:0;-webkit-transition:none;-moz-transition:none;transition:none; }
11
  #content .fv-player-video-checker.is-open, .fv-player-video-checker.is-open { color: black !important; background-color: #FFFFE0; margin: 0; padding: 0 12px; pointer-events: auto; border-radius: 0; border: none; line-height: 15px; z-index: 100; width: 100%; font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif }
12
  #content .fv-player-video-checker.is-open strong, .fv-player-video-checker.is-open strong { font-weight: bold; }
13
- #content .fv-player-video-checker.is-open p, .fv-player-video-checker.is-open p { font-family: sans-serif; margin: 0.5em 0; padding: 2px; color: #5b5b5b; }
14
  .is-open p tt, .fv-player-video-checker.is-open blockquote { color: #000; font-size: 12px; }
15
  .is-open p tt.bluelink { color: #4189A7; }
16
 
@@ -169,7 +170,7 @@ table.fv-player-popup-formats td:first-child { width: 72px }
169
  display: none;
170
  }
171
 
172
- .show-info, .show-info:hover, .show-info:active, .show-info:focus { color: #444; box-shadow: none; }
173
  .fv-player-admin-tooltip {
174
  position: absolute;
175
  background: white;
1
  #content .fv-player-video-checker, .fv-player-video-checker { pointer-events: none; position: absolute; top: 0; left: 0; z-index: 20; }
2
+ #content .flowplayer.is-audio .fv-player-video-checker, .flowplayer.is-audio .fv-player-video-checker { color: unset !important; top: -40px; }
3
  #content .flowplayer .fv-player-video-checker small, .flowplayer .fv-player-video-checker small { pointer-events: auto; position:relative;left:15px;top:10px;-webkit-transition:all .15s 0s;-moz-transition:all .15s 0s;transition:all .15s 0s }
4
+ #content .flowplayer.is-mouseover.is-ready:not(.is-audio) .fv-player-video-checker small,
5
+ .flowplayer.is-mouseover.is-ready:not(.is-audio) .fv-player-video-checker small,
6
+ #content .flowplayer.is-ready.is-paused:not(.is-audio) .fv-player-video-checker small,
7
+ .flowplayer.is-ready.is-paused:not(.is-audio) .fv-player-video-checker small { top: 3em }
8
  #content .flowplayer .fv-player-video-checker.is-open small,
9
  .flowplayer .fv-player-video-checker.is-open small,
10
  #content .flowplayer.has-video-checker .fv-player-video-checker.is-open small,
11
+ .flowplayer.has-video-checker .fv-player-video-checker.is-open small { top:0 !important;left:0;-webkit-transition:none;-moz-transition:none;transition:none; color: black }
12
  #content .fv-player-video-checker.is-open, .fv-player-video-checker.is-open { color: black !important; background-color: #FFFFE0; margin: 0; padding: 0 12px; pointer-events: auto; border-radius: 0; border: none; line-height: 15px; z-index: 100; width: 100%; font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif }
13
  #content .fv-player-video-checker.is-open strong, .fv-player-video-checker.is-open strong { font-weight: bold; }
14
+ #content .fv-player-video-checker.is-open p, .fv-player-video-checker.is-open p { font-family: sans-serif; margin: 0.5em 0; padding: 2px; color: #5b5b5b; word-break: break-word; }
15
  .is-open p tt, .fv-player-video-checker.is-open blockquote { color: #000; font-size: 12px; }
16
  .is-open p tt.bluelink { color: #4189A7; }
17
 
170
  display: none;
171
  }
172
 
173
+ .show-info, .show-info:hover, .show-info:active, .show-info:focus { color: #444; box-shadow: none; text-decoration: none; }
174
  .fv-player-admin-tooltip {
175
  position: absolute;
176
  background: white;
css/flowplayer.css CHANGED
@@ -1773,8 +1773,8 @@ article .entry-content .fvfp_admin_error p { line-height: 18px }
1773
  .is-audio + .fp-playlist-external a h4,.entry-content .is-audio + .fp-playlist-external a h4 { display: block;opacity:1;position:relative;text-align:left;font-size:13px;padding:0;clear:none;left:auto;width:auto;background-color:transparent;color:inherit }
1774
  .is-audio + .fp-playlist-external a h4 span,.entry-content .is-audio + .fp-playlist-external a h4 span { position:relative;top:auto;padding:0;transform:none }
1775
  .is-audio + .fp-playlist-external a h4:before,.entry-content .is-audio + .fp-playlist-external a h4:before { content: counter(fv-playlist-counter, decimal-leading-zero) ". ";float:left;min-width:26px;color:#adadad;font-weight:400 }
1776
- .flowplayer.fixed-controls.is-audio, .flowplayer.skin-custom.fixed-controls.is-audio { margin-bottom:0;height:2.8em }
1777
- .flowplayer.fixed-controls.is-audio.fp-slim { height:2.4em }
1778
  .flowplayer.is-audio .fv-ab-loop,.flowplayer.fixed-controls.is-audio .fv-ab-loop {bottom:-28px;padding-left:82px}
1779
  .flowplayer.is-loading.is-audio .fp-controls { display:flex }
1780
  .flowplayer.is-audio.is-loading .fp-playbtn {opacity:0}
@@ -1816,6 +1816,57 @@ article .entry-content .fvfp_admin_error p { line-height: 18px }
1816
  padding-top: 0;
1817
  }
1818
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1819
  /* Media Queries - done */
1820
 
1821
  @media (max-width: 56.1875em){
@@ -1841,6 +1892,40 @@ article .entry-content .fvfp_admin_error p { line-height: 18px }
1841
  .fp-playlist-vertical-wrapper .fp-playlist-vertical a,.fp-playlist-vertical a {width:49.5%;float:left;margin: .75% 0 0 1%}
1842
  .fp-playlist-only-captions.fp-playlist-vertical a {width:100%;float:none;margin:8px 0}
1843
  .fp-playlist-vertical a:nth-child(2n+1) {clear:both;margin-left:0}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1844
  }
1845
  @media only screen and (max-width: 29.9375em) {
1846
  .flowplayer .fv_player_popup {width:100%;font-size:12px;top:0;}
@@ -1870,7 +1955,6 @@ article .entry-content .fvfp_admin_error p { line-height: 18px }
1870
  }
1871
  }
1872
 
1873
-
1874
  @media screen and (min-width: 1020px) {
1875
  .fp-playlist-external.fp-playlist-polaroid a,
1876
  .entry-content .fp-playlist-external.fp-playlist-polaroid a {
@@ -1885,61 +1969,6 @@ article .entry-content .fvfp_admin_error p { line-height: 18px }
1885
  .fp-playlist-external.fp-playlist-polaroid a:nth-child(4n+1) {
1886
  clear: both;
1887
  }
1888
- .fp-player a.fp-sticky {
1889
- display: none;
1890
- }
1891
- .flowplayer.is-stickable a.fp-sticky {
1892
- display: block;
1893
- float: right;
1894
- }
1895
- .flowplayer a.fp-sticky:before {
1896
- content: "\e10f";
1897
- }
1898
- div.fp-player.is-sticky-left-top, div.fp-player.is-sticky-right-top , div.fp-player.is-sticky-left-bottom , div.fp-player.is-sticky-right-bottom {
1899
- transform: translateX(-20px);
1900
- -ms-transform: translateX(-20px);
1901
- -webkit-transform: translateX(-20px);
1902
- transition: width .5s ease-in-out, height .5s ease-in-out, transform .5s ease-in-out;
1903
- transition: transform .5s;
1904
- }
1905
- div.fp-player.is-sticky-left-top, div.fp-player.is-sticky-right-top , div.fp-player.is-sticky-left-bottom , div.fp-player.is-sticky-right-bottom {
1906
- position: fixed;
1907
- top: 50px;
1908
- right: 30px;
1909
- left: auto;
1910
- max-width: 50%;
1911
- z-index: 999;
1912
- }
1913
- div.fp-player.is-sticky-left-top {
1914
- transform: translateX(20px);
1915
- -ms-transform: translateX(20px);
1916
- -webkit-transform: translateX(20px);
1917
- top: 50px;
1918
- left: 50px;
1919
- right: auto;
1920
- bottom: auto;
1921
- }
1922
- div.fp-player.is-sticky-right-top {
1923
- top: 50px;
1924
- right: 30px;
1925
- left: auto;
1926
- bottom: auto;
1927
- }
1928
- div.fp-player.is-sticky-left-bottom {
1929
- transform: translateX(20px);
1930
- -ms-transform: translateX(20px);
1931
- -webkit-transform: translateX(20px);
1932
- bottom: 50px;
1933
- left: 30px;
1934
- right: auto;
1935
- top: auto;
1936
- }
1937
- div.fp-player.is-sticky-right-bottom {
1938
- bottom: 50px;
1939
- right: 30px;
1940
- left: auto;
1941
- top: auto;
1942
- }
1943
  }
1944
 
1945
  /* Profile viedeo fix for EDD */
1773
  .is-audio + .fp-playlist-external a h4,.entry-content .is-audio + .fp-playlist-external a h4 { display: block;opacity:1;position:relative;text-align:left;font-size:13px;padding:0;clear:none;left:auto;width:auto;background-color:transparent;color:inherit }
1774
  .is-audio + .fp-playlist-external a h4 span,.entry-content .is-audio + .fp-playlist-external a h4 span { position:relative;top:auto;padding:0;transform:none }
1775
  .is-audio + .fp-playlist-external a h4:before,.entry-content .is-audio + .fp-playlist-external a h4:before { content: counter(fv-playlist-counter, decimal-leading-zero) ". ";float:left;min-width:26px;color:#adadad;font-weight:400 }
1776
+ .flowplayer.fixed-controls.is-audio, .flowplayer.skin-custom.fixed-controls.is-audio { margin-bottom:2.8em;height:2.8em }
1777
+ .flowplayer.fixed-controls.is-audio.fp-slim { height:2.8em }
1778
  .flowplayer.is-audio .fv-ab-loop,.flowplayer.fixed-controls.is-audio .fv-ab-loop {bottom:-28px;padding-left:82px}
1779
  .flowplayer.is-loading.is-audio .fp-controls { display:flex }
1780
  .flowplayer.is-audio.is-loading .fp-playbtn {opacity:0}
1816
  padding-top: 0;
1817
  }
1818
 
1819
+ .fp-player a.fp-sticky {
1820
+ display: none;
1821
+ }
1822
+ .flowplayer.is-stickable a.fp-sticky {
1823
+ display: block;
1824
+ float: right;
1825
+ }
1826
+ .flowplayer a.fp-sticky:before {
1827
+ content: "\e10f";
1828
+ }
1829
+ div.fp-player.is-sticky {
1830
+ transform: translateX(-20px);
1831
+ -ms-transform: translateX(-20px);
1832
+ -webkit-transform: translateX(-20px);
1833
+ transition: transform .5s ease-in-out;
1834
+ position: fixed;
1835
+ max-width: 80%;
1836
+ background: black;
1837
+ z-index: 999;
1838
+ }
1839
+ div.fp-player.is-sticky-left-top {
1840
+ transform: translateX(20px);
1841
+ -ms-transform: translateX(20px);
1842
+ -webkit-transform: translateX(20px);
1843
+ top: 50px;
1844
+ left: 50px;
1845
+ right: auto;
1846
+ bottom: auto;
1847
+ }
1848
+ div.fp-player.is-sticky-right-top {
1849
+ top: 50px;
1850
+ right: 30px;
1851
+ left: auto;
1852
+ bottom: auto;
1853
+ }
1854
+ div.fp-player.is-sticky-left-bottom {
1855
+ transform: translateX(20px);
1856
+ -ms-transform: translateX(20px);
1857
+ -webkit-transform: translateX(20px);
1858
+ bottom: 50px;
1859
+ left: 30px;
1860
+ right: auto;
1861
+ top: auto;
1862
+ }
1863
+ div.fp-player.is-sticky-right-bottom {
1864
+ bottom: 50px;
1865
+ right: 30px;
1866
+ left: auto;
1867
+ top: auto;
1868
+ }
1869
+
1870
  /* Media Queries - done */
1871
 
1872
  @media (max-width: 56.1875em){
1892
  .fp-playlist-vertical-wrapper .fp-playlist-vertical a,.fp-playlist-vertical a {width:49.5%;float:left;margin: .75% 0 0 1%}
1893
  .fp-playlist-only-captions.fp-playlist-vertical a {width:100%;float:none;margin:8px 0}
1894
  .fp-playlist-vertical a:nth-child(2n+1) {clear:both;margin-left:0}
1895
+
1896
+ div.fp-player.is-sticky {
1897
+ transform: translateX(0);
1898
+ -ms-transform: translateX(0);
1899
+ -webkit-transform: translateX(0);
1900
+ }
1901
+ div.fp-player.is-sticky-left-top {
1902
+ top: 0;
1903
+ left: 0;
1904
+ }
1905
+ div.fp-player.is-sticky-right-top {
1906
+ top: 0;
1907
+ right: 0;
1908
+ }
1909
+ div.fp-player.is-sticky-left-bottom {
1910
+ bottom: 0;
1911
+ left: 0;
1912
+ }
1913
+ div.fp-player.is-sticky-right-bottom {
1914
+ bottom: 0;
1915
+ right: 0;
1916
+ }
1917
+ .flowplayer.fixed-controls div.fp-player.is-sticky-left-bottom,
1918
+ .flowplayer.fixed-controls div.fp-player.is-sticky-right-bottom {
1919
+ bottom: 2.4em;
1920
+ }
1921
+ .flowplayer.fixed-controls.fp-full:not(.fp-slim) div.fp-player.is-sticky-left-bottom,
1922
+ .flowplayer.fixed-controls.fp-full:not(.fp-slim) div.fp-player.is-sticky-right-bottom {
1923
+ bottom: 2.8em;
1924
+ }
1925
+ .flowplayer.fixed-controls.has-abloop div.fp-player.is-sticky-left-bottom,
1926
+ .flowplayer.fixed-controls.has-abloop div.fp-player.is-sticky-right-bottom {
1927
+ bottom: 4em;
1928
+ }
1929
  }
1930
  @media only screen and (max-width: 29.9375em) {
1931
  .flowplayer .fv_player_popup {width:100%;font-size:12px;top:0;}
1955
  }
1956
  }
1957
 
 
1958
  @media screen and (min-width: 1020px) {
1959
  .fp-playlist-external.fp-playlist-polaroid a,
1960
  .entry-content .fp-playlist-external.fp-playlist-polaroid a {
1969
  .fp-playlist-external.fp-playlist-polaroid a:nth-child(4n+1) {
1970
  clear: both;
1971
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1972
  }
1973
 
1974
  /* Profile viedeo fix for EDD */
css/fonts/fpicons.svg CHANGED
@@ -1,6 +1,6 @@
1
  <?xml version="1.0" standalone="no"?>
2
- <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
- <svg xmlns="http://www.w3.org/2000/svg">
4
  <metadata>Generated by IcoMoon</metadata>
5
  <defs>
6
  <font id="fpicons" horiz-adv-x="1024">
1
  <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+ <svg xmlns="https://www.w3.org/2000/svg">
4
  <metadata>Generated by IcoMoon</metadata>
5
  <defs>
6
  <font id="fpicons" horiz-adv-x="1024">
css/fvp-icon-sprite.svg CHANGED
@@ -1,4 +1,4 @@
1
- <svg style="position: absolute; width: 0; height: 0; overflow: hidden;" class="fvp-icon" xmlns="http://www.w3.org/2000/svg">
2
  <defs>
3
  <g id="fvp-playlist">
4
  <path class="svg-color" d="M4.972,44.723C2.984,42.668,2,40.282,2,37.543v-35.9h14.36v31.792h37.345V18.057l24.629,22.574
1
+ <svg style="position: absolute; width: 0; height: 0; overflow: hidden;" class="fvp-icon" xmlns="https://www.w3.org/2000/svg">
2
  <defs>
3
  <g id="fvp-playlist">
4
  <path class="svg-color" d="M4.972,44.723C2.984,42.668,2,40.282,2,37.543v-35.9h14.36v31.792h37.345V18.057l24.629,22.574
css/icons/flowplayer.svg CHANGED
@@ -1,6 +1,6 @@
1
  <?xml version="1.0" standalone="no"?>
2
- <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
- <svg xmlns="http://www.w3.org/2000/svg">
4
  <metadata>Generated by IcoMoon</metadata>
5
  <defs>
6
  <font id="icomoon" horiz-adv-x="1024">
1
  <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+ <svg xmlns="https://www.w3.org/2000/svg">
4
  <metadata>Generated by IcoMoon</metadata>
5
  <defs>
6
  <font id="icomoon" horiz-adv-x="1024">
css/img/no-play-white.svg CHANGED
@@ -1,3 +1,3 @@
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="128" height="128"><defs><path d="M619.54 319.18C619.54 484.05 485.69 617.91 320.82 617.91C155.95 617.91 22.09 484.05 22.09 319.18C22.09 154.31 155.95 20.46 320.82 20.46C485.69 20.46 619.54 154.31 619.54 319.18Z" id="a1kyPCZmWY"></path><path d="M90.2 520.29L520.29 90.2L550.62 120.53L120.53 550.62L90.2 520.29Z" id="a1eG6Iy9mS"></path></defs><g><g><g><use xlink:href="#a1kyPCZmWY" opacity="1" fill="#1e89ad" fill-opacity="0"></use><g><use xlink:href="#a1kyPCZmWY" opacity="1" fill-opacity="0" stroke="#ffffff" stroke-width="36" stroke-opacity="1"></use></g></g><g><use xlink:href="#a1eG6Iy9mS" opacity="1" fill="#ffffff" fill-opacity="0.99"></use></g></g></g></svg>
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="128" height="128"><defs><path d="M619.54 319.18C619.54 484.05 485.69 617.91 320.82 617.91C155.95 617.91 22.09 484.05 22.09 319.18C22.09 154.31 155.95 20.46 320.82 20.46C485.69 20.46 619.54 154.31 619.54 319.18Z" id="a1kyPCZmWY"></path><path d="M90.2 520.29L520.29 90.2L550.62 120.53L120.53 550.62L90.2 520.29Z" id="a1eG6Iy9mS"></path></defs><g><g><g><use xlink:href="#a1kyPCZmWY" opacity="1" fill="#1e89ad" fill-opacity="0"></use><g><use xlink:href="#a1kyPCZmWY" opacity="1" fill-opacity="0" stroke="#ffffff" stroke-width="36" stroke-opacity="1"></use></g></g><g><use xlink:href="#a1eG6Iy9mS" opacity="1" fill="#ffffff" fill-opacity="0.99"></use></g></g></g></svg>
css/shortcode-editor.css CHANGED
@@ -50,7 +50,10 @@
50
  #fv_player_boxTitle{ display:none!important; }
51
  #fv_player_boxLoadedContent{ margin-top:0; }
52
 
53
- #fv-player-shortcode-editor-left{ float: left; width:42%; margin-right: 1% }
 
 
 
54
  #fv-player-shortcode-editor-right{ float: left; width:57%; }
55
  #fv-player-shortcode-editor #fv_wp_flowplayer_field_player_name { width: 96%; margin: 0 0 6px; }
56
  .fv-player-tab{position:relative;}
@@ -299,3 +302,40 @@ a #add-format, a #add-rtmp {
299
  }
300
 
301
  #fv-player-shortcode-editor .fv-player-playlist-item-title, #fv-player-shortcode-editor .fv-player-playlist-item-title:hover{ margin:0;border:0;background:transparent; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  #fv_player_boxTitle{ display:none!important; }
51
  #fv_player_boxLoadedContent{ margin-top:0; }
52
 
53
+ #fv-player-shortcode-editor-left{
54
+ float: left; width:42%; margin-right: 1%;
55
+ overflow-x: hidden;
56
+ }
57
  #fv-player-shortcode-editor-right{ float: left; width:57%; }
58
  #fv-player-shortcode-editor #fv_wp_flowplayer_field_player_name { width: 96%; margin: 0 0 6px; }
59
  .fv-player-tab{position:relative;}
302
  }
303
 
304
  #fv-player-shortcode-editor .fv-player-playlist-item-title, #fv-player-shortcode-editor .fv-player-playlist-item-title:hover{ margin:0;border:0;background:transparent; }
305
+
306
+ body.elementor-editor-active #fv-player-shortcode-editor .button, body.elementor-editor-active #fv-player-shortcode-editor .button-primary {
307
+ display: inline-block;
308
+ text-decoration: none;
309
+ font-size: 13px;
310
+ line-height: 2.15384615;
311
+ min-height: 30px;
312
+ margin: 0;
313
+ padding: 0 10px;
314
+ cursor: pointer;
315
+ border-width: 1px;
316
+ border-style: solid;
317
+ -webkit-appearance: none;
318
+ border-radius: 3px;
319
+ white-space: nowrap;
320
+ box-sizing: border-box;
321
+ color: #2271b1;
322
+ border-color: #2271b1;
323
+ background: #f6f7f7;
324
+ }
325
+ body.elementor-editor-active #fv-player-shortcode-editor .button-primary {
326
+ background: #2271b1;
327
+ border-color: #2271b1;
328
+ color: #fff;
329
+ text-decoration: none;
330
+ text-shadow: none;
331
+ }
332
+ body.elementor-editor-active #fv-player-shortcode-editor .button:hover {
333
+ background: #f0f0f1;
334
+ border-color: #0a4b78;
335
+ color: #0a4b78;
336
+ }
337
+ body.elementor-editor-active #fv-player-shortcode-editor .button-primary:hover {
338
+ background: #135e96;
339
+ border-color: #135e96;
340
+ color: #fff;
341
+ }
css/sitemap-index.xsl CHANGED
@@ -6,7 +6,7 @@
6
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
7
  <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
8
  <xsl:template match="/">
9
- <html xmlns="http://www.w3.org/1999/xhtml">
10
  <head>
11
  <title>FV Player Video Sitemap - Index</title>
12
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
7
  <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
8
  <xsl:template match="/">
9
+ <html xmlns="https://www.w3.org/1999/xhtml">
10
  <head>
11
  <title>FV Player Video Sitemap - Index</title>
12
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
flowplayer.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: FV Player
4
  Plugin URI: http://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer
5
  Description: Formerly FV WordPress Flowplayer. Supports MP4, HLS, MPEG-DASH, WebM and OGV. Advanced features such as overlay ads or popups. Uses Flowplayer 7.2.7.
6
- Version: 7.5.15.727
7
  Author URI: http://foliovision.com/
8
  License: GPL-3.0
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.txt
@@ -27,7 +27,7 @@ License URI: http://www.gnu.org/licenses/gpl-3.0.txt
27
  */
28
 
29
  global $fv_wp_flowplayer_ver;
30
- $fv_wp_flowplayer_ver = '7.5.15.727';
31
  $fv_wp_flowplayer_core_ver = '7.2.7.2';
32
  include_once( dirname( __FILE__ ) . '/includes/extra-functions.php' );
33
  if( file_exists( dirname( __FILE__ ) . '/includes/module.php' ) ) {
@@ -90,6 +90,11 @@ if( is_admin() ) {
90
  include_once(dirname( __FILE__ ) . '/models/media-browser-s3.php');
91
  }
92
  include_once(dirname( __FILE__ ) . '/models/system-info.php');
 
 
 
 
 
93
  register_deactivation_hook( __FILE__, 'flowplayer_deactivate' );
94
  }
95
 
@@ -104,10 +109,6 @@ include_once(dirname( __FILE__ ). '/models/migration-wizard.php');
104
 
105
  include_once(dirname( __FILE__ ) . '/models/stats.php');
106
 
107
- include_once(dirname( __FILE__ ). '/models/conversion/conversion-base.class.php');
108
- include_once(dirname( __FILE__ ). '/models/conversion/shortcode2DB.class.php');
109
- include_once(dirname( __FILE__ ) . '/models/conversion.php');
110
-
111
  add_action('plugins_loaded', 'fv_player_bunny_stream_include' );
112
 
113
  if( !function_exists( 'fv_player_bunny_stream_include' ) ) {
3
  Plugin Name: FV Player
4
  Plugin URI: http://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer
5
  Description: Formerly FV WordPress Flowplayer. Supports MP4, HLS, MPEG-DASH, WebM and OGV. Advanced features such as overlay ads or popups. Uses Flowplayer 7.2.7.
6
+ Version: 7.5.21.727
7
  Author URI: http://foliovision.com/
8
  License: GPL-3.0
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.txt
27
  */
28
 
29
  global $fv_wp_flowplayer_ver;
30
+ $fv_wp_flowplayer_ver = '7.5.21.727';
31
  $fv_wp_flowplayer_core_ver = '7.2.7.2';
32
  include_once( dirname( __FILE__ ) . '/includes/extra-functions.php' );
33
  if( file_exists( dirname( __FILE__ ) . '/includes/module.php' ) ) {
90
  include_once(dirname( __FILE__ ) . '/models/media-browser-s3.php');
91
  }
92
  include_once(dirname( __FILE__ ) . '/models/system-info.php');
93
+
94
+ include_once(dirname( __FILE__ ). '/models/conversion/conversion-base.class.php');
95
+ include_once(dirname( __FILE__ ). '/models/conversion/shortcode2DB.class.php');
96
+ include_once(dirname( __FILE__ ) . '/models/conversion.php');
97
+
98
  register_deactivation_hook( __FILE__, 'flowplayer_deactivate' );
99
  }
100
 
109
 
110
  include_once(dirname( __FILE__ ) . '/models/stats.php');
111
 
 
 
 
 
112
  add_action('plugins_loaded', 'fv_player_bunny_stream_include' );
113
 
114
  if( !function_exists( 'fv_player_bunny_stream_include' ) ) {
flowplayer/flowplayer.dashjs.min.js CHANGED
@@ -148,7 +148,7 @@
148
  console.log('restoring quality '+localStorage.FVPlayerDashQuality+' => '+key);
149
  }
150
  });
151
- if( player.conf.dash.initialVideoQuality == 'restore' ) initialVideoQuality = player.conf.dash.initialVideoQuality = vsets.length - 1; // if nothing has been found, pick the biggest
152
  }
153
 
154
  if (!qselConf) {
148
  console.log('restoring quality '+localStorage.FVPlayerDashQuality+' => '+key);
149
  }
150
  });
151
+ if( player.conf.dash && player.conf.dash.initialVideoQuality == 'restore' ) initialVideoQuality = player.conf.dash.initialVideoQuality = vsets.length - 1; // if nothing has been found, pick the biggest
152
  }
153
 
154
  if (!qselConf) {
flowplayer/fv-player-loader.babel.js CHANGED
@@ -12,7 +12,7 @@
12
  }
13
 
14
  var filter = document.createElement('div');
15
- filter.innerHTML = '<svg class="fp-filters" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0"><defs><filter id="f1" x="-20%" y="-20%" width="200%" height="200%"><feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" /><feColorMatrix result="matrixOut" in="offOut" type="matrix" values="0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.4 0" /><feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="4" /><feBlend in="SourceGraphic" in2="blurOut" mode="normal" /></filter></defs></svg>';
16
  filter.style.width = 0;
17
  filter.style.height = 0;
18
  filter.style.overflow = 'hidden';
@@ -39,10 +39,10 @@
39
  play_icon = document.createElement('div');
40
  play_icon.className = 'fp-play fp-visible';
41
  play_icon.innerHTML = '<a class="fp-icon fp-playbtn"></a>\
42
- <svg class="fp-play-rounded-fill" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.a{fill:#000;opacity:0.65;}.b{fill:#fff;opacity:1.0;}</style></defs><title>play-rounded-fill</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="b" d="M35.942,35.2323c0-4.7289,3.3506-6.6637,7.446-4.2971L68.83,45.6235c4.0956,2.364,4.0956,6.2319,0,8.5977L43.388,68.91c-4.0954,2.364-7.446.43-7.446-4.2979Z" filter="url(#f1)"/></svg>\
43
- <svg class="fp-play-rounded-outline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 99.844 99.8434"><defs><style>.fp-color-play{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-rounded-outline</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="controlbutton" d="M41.0359,71.19a5.0492,5.0492,0,0,1-2.5575-.6673c-1.8031-1.041-2.7958-3.1248-2.7958-5.8664V35.1887c0-2.7429.9933-4.8272,2.797-5.8676,1.8025-1.0422,4.1034-.86,6.48.5143L70.4782,44.5672c2.3751,1.3711,3.6826,3.2725,3.6832,5.3545s-1.3076,3.9845-3.6832,5.3562L44.9592,70.0114A7.9384,7.9384,0,0,1,41.0359,71.19Zm.0065-40.123a2.6794,2.6794,0,0,0-1.3582.3413c-1.0263.5926-1.5912,1.9349-1.5912,3.78V64.6563c0,1.8449.5649,3.1866,1.5906,3.7791,1.0281.5932,2.4733.4108,4.07-.512L69.273,53.1906c1.5983-.9227,2.478-2.0838,2.478-3.2689s-.88-2.3445-2.478-3.2666L43.754,31.9227A5.5685,5.5685,0,0,0,41.0423,31.0671Z" filter="url(#f1)"/></svg>\
44
- <svg class="fp-play-sharp-fill" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.fp-color-play{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-sharp-fill</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><polygon class="controlbutton" points="73.601 50 37.968 70.573 37.968 29.427 73.601 50" filter="url(#f1)"/></svg>\
45
- <svg class="fp-play-sharp-outline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 99.844 99.8434"><defs><style>.controlbuttonbg{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-sharp-outline</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="controlbutton" d="M36.9443,72.2473V27.2916L75.8776,49.77Zm2.2-41.1455V68.4371L71.4776,49.77Z" filter="url(#f1)"/></svg>'.replace(/url\(#/g, 'url(' + window.location.href.replace(window.location.hash, "").replace(/\#$/g, '') + '#');
46
  preload.style.display = 'none';
47
  parent.appendChild(play_icon);
48
  });
12
  }
13
 
14
  var filter = document.createElement('div');
15
+ filter.innerHTML = '<svg class="fp-filters" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 0 0"><defs><filter id="f1" x="-20%" y="-20%" width="200%" height="200%"><feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" /><feColorMatrix result="matrixOut" in="offOut" type="matrix" values="0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.4 0" /><feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="4" /><feBlend in="SourceGraphic" in2="blurOut" mode="normal" /></filter></defs></svg>';
16
  filter.style.width = 0;
17
  filter.style.height = 0;
18
  filter.style.overflow = 'hidden';
39
  play_icon = document.createElement('div');
40
  play_icon.className = 'fp-play fp-visible';
41
  play_icon.innerHTML = '<a class="fp-icon fp-playbtn"></a>\
42
+ <svg class="fp-play-rounded-fill" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.a{fill:#000;opacity:0.65;}.b{fill:#fff;opacity:1.0;}</style></defs><title>play-rounded-fill</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="b" d="M35.942,35.2323c0-4.7289,3.3506-6.6637,7.446-4.2971L68.83,45.6235c4.0956,2.364,4.0956,6.2319,0,8.5977L43.388,68.91c-4.0954,2.364-7.446.43-7.446-4.2979Z" filter="url(#f1)"/></svg>\
43
+ <svg class="fp-play-rounded-outline" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 99.844 99.8434"><defs><style>.fp-color-play{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-rounded-outline</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="controlbutton" d="M41.0359,71.19a5.0492,5.0492,0,0,1-2.5575-.6673c-1.8031-1.041-2.7958-3.1248-2.7958-5.8664V35.1887c0-2.7429.9933-4.8272,2.797-5.8676,1.8025-1.0422,4.1034-.86,6.48.5143L70.4782,44.5672c2.3751,1.3711,3.6826,3.2725,3.6832,5.3545s-1.3076,3.9845-3.6832,5.3562L44.9592,70.0114A7.9384,7.9384,0,0,1,41.0359,71.19Zm.0065-40.123a2.6794,2.6794,0,0,0-1.3582.3413c-1.0263.5926-1.5912,1.9349-1.5912,3.78V64.6563c0,1.8449.5649,3.1866,1.5906,3.7791,1.0281.5932,2.4733.4108,4.07-.512L69.273,53.1906c1.5983-.9227,2.478-2.0838,2.478-3.2689s-.88-2.3445-2.478-3.2666L43.754,31.9227A5.5685,5.5685,0,0,0,41.0423,31.0671Z" filter="url(#f1)"/></svg>\
44
+ <svg class="fp-play-sharp-fill" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.fp-color-play{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-sharp-fill</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><polygon class="controlbutton" points="73.601 50 37.968 70.573 37.968 29.427 73.601 50" filter="url(#f1)"/></svg>\
45
+ <svg class="fp-play-sharp-outline" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 99.844 99.8434"><defs><style>.controlbuttonbg{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-sharp-outline</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="controlbutton" d="M36.9443,72.2473V27.2916L75.8776,49.77Zm2.2-41.1455V68.4371L71.4776,49.77Z" filter="url(#f1)"/></svg>'.replace(/url\(#/g, 'url(' + window.location.href.replace(window.location.hash, "").replace(/\#$/g, '') + '#');
46
  preload.style.display = 'none';
47
  parent.appendChild(play_icon);
48
  });
flowplayer/fv-player-loader.dev.js CHANGED
@@ -10,7 +10,7 @@
10
  }
11
 
12
  var filter = document.createElement('div');
13
- filter.innerHTML = '<svg class="fp-filters" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0"><defs><filter id="f1" x="-20%" y="-20%" width="200%" height="200%"><feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" /><feColorMatrix result="matrixOut" in="offOut" type="matrix" values="0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.4 0" /><feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="4" /><feBlend in="SourceGraphic" in2="blurOut" mode="normal" /></filter></defs></svg>';
14
  filter.style.width = 0;
15
  filter.style.height = 0;
16
  filter.style.overflow = 'hidden';
@@ -39,10 +39,10 @@
39
  play_icon.className = 'fp-play fp-visible';
40
 
41
  play_icon.innerHTML = '<a class="fp-icon fp-playbtn"></a>\
42
- <svg class="fp-play-rounded-fill" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.a{fill:#000;opacity:0.65;}.b{fill:#fff;opacity:1.0;}</style></defs><title>play-rounded-fill</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="b" d="M35.942,35.2323c0-4.7289,3.3506-6.6637,7.446-4.2971L68.83,45.6235c4.0956,2.364,4.0956,6.2319,0,8.5977L43.388,68.91c-4.0954,2.364-7.446.43-7.446-4.2979Z" filter="url(#f1)"/></svg>\
43
- <svg class="fp-play-rounded-outline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 99.844 99.8434"><defs><style>.fp-color-play{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-rounded-outline</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="controlbutton" d="M41.0359,71.19a5.0492,5.0492,0,0,1-2.5575-.6673c-1.8031-1.041-2.7958-3.1248-2.7958-5.8664V35.1887c0-2.7429.9933-4.8272,2.797-5.8676,1.8025-1.0422,4.1034-.86,6.48.5143L70.4782,44.5672c2.3751,1.3711,3.6826,3.2725,3.6832,5.3545s-1.3076,3.9845-3.6832,5.3562L44.9592,70.0114A7.9384,7.9384,0,0,1,41.0359,71.19Zm.0065-40.123a2.6794,2.6794,0,0,0-1.3582.3413c-1.0263.5926-1.5912,1.9349-1.5912,3.78V64.6563c0,1.8449.5649,3.1866,1.5906,3.7791,1.0281.5932,2.4733.4108,4.07-.512L69.273,53.1906c1.5983-.9227,2.478-2.0838,2.478-3.2689s-.88-2.3445-2.478-3.2666L43.754,31.9227A5.5685,5.5685,0,0,0,41.0423,31.0671Z" filter="url(#f1)"/></svg>\
44
- <svg class="fp-play-sharp-fill" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.fp-color-play{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-sharp-fill</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><polygon class="controlbutton" points="73.601 50 37.968 70.573 37.968 29.427 73.601 50" filter="url(#f1)"/></svg>\
45
- <svg class="fp-play-sharp-outline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 99.844 99.8434"><defs><style>.controlbuttonbg{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-sharp-outline</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="controlbutton" d="M36.9443,72.2473V27.2916L75.8776,49.77Zm2.2-41.1455V68.4371L71.4776,49.77Z" filter="url(#f1)"/></svg>'.replace(/url\(#/g, 'url(' + window.location.href.replace(window.location.hash, "").replace(/\#$/g, '') + '#');
46
 
47
  preload.style.display = 'none';
48
  parent.appendChild(play_icon);
10
  }
11
 
12
  var filter = document.createElement('div');
13
+ filter.innerHTML = '<svg class="fp-filters" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 0 0"><defs><filter id="f1" x="-20%" y="-20%" width="200%" height="200%"><feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" /><feColorMatrix result="matrixOut" in="offOut" type="matrix" values="0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.3 0 0 0 0 0 0.4 0" /><feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="4" /><feBlend in="SourceGraphic" in2="blurOut" mode="normal" /></filter></defs></svg>';
14
  filter.style.width = 0;
15
  filter.style.height = 0;
16
  filter.style.overflow = 'hidden';
39
  play_icon.className = 'fp-play fp-visible';
40
 
41
  play_icon.innerHTML = '<a class="fp-icon fp-playbtn"></a>\
42
+ <svg class="fp-play-rounded-fill" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.a{fill:#000;opacity:0.65;}.b{fill:#fff;opacity:1.0;}</style></defs><title>play-rounded-fill</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="b" d="M35.942,35.2323c0-4.7289,3.3506-6.6637,7.446-4.2971L68.83,45.6235c4.0956,2.364,4.0956,6.2319,0,8.5977L43.388,68.91c-4.0954,2.364-7.446.43-7.446-4.2979Z" filter="url(#f1)"/></svg>\
43
+ <svg class="fp-play-rounded-outline" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 99.844 99.8434"><defs><style>.fp-color-play{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-rounded-outline</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="controlbutton" d="M41.0359,71.19a5.0492,5.0492,0,0,1-2.5575-.6673c-1.8031-1.041-2.7958-3.1248-2.7958-5.8664V35.1887c0-2.7429.9933-4.8272,2.797-5.8676,1.8025-1.0422,4.1034-.86,6.48.5143L70.4782,44.5672c2.3751,1.3711,3.6826,3.2725,3.6832,5.3545s-1.3076,3.9845-3.6832,5.3562L44.9592,70.0114A7.9384,7.9384,0,0,1,41.0359,71.19Zm.0065-40.123a2.6794,2.6794,0,0,0-1.3582.3413c-1.0263.5926-1.5912,1.9349-1.5912,3.78V64.6563c0,1.8449.5649,3.1866,1.5906,3.7791,1.0281.5932,2.4733.4108,4.07-.512L69.273,53.1906c1.5983-.9227,2.478-2.0838,2.478-3.2689s-.88-2.3445-2.478-3.2666L43.754,31.9227A5.5685,5.5685,0,0,0,41.0423,31.0671Z" filter="url(#f1)"/></svg>\
44
+ <svg class="fp-play-sharp-fill" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.fp-color-play{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-sharp-fill</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><polygon class="controlbutton" points="73.601 50 37.968 70.573 37.968 29.427 73.601 50" filter="url(#f1)"/></svg>\
45
+ <svg class="fp-play-sharp-outline" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 99.844 99.8434"><defs><style>.controlbuttonbg{opacity:0.65;}.controlbutton{fill:#fff;}</style></defs><title>play-sharp-outline</title><path class="fp-color-play" d="M49.9217-.078a50,50,0,1,0,50,50A50.0564,50.0564,0,0,0,49.9217-.078Z"/><path class="controlbutton" d="M36.9443,72.2473V27.2916L75.8776,49.77Zm2.2-41.1455V68.4371L71.4776,49.77Z" filter="url(#f1)"/></svg>'.replace(/url\(#/g, 'url(' + window.location.href.replace(window.location.hash, "").replace(/\#$/g, '') + '#');
46
 
47
  preload.style.display = 'none';
48
  parent.appendChild(play_icon);
flowplayer/fv-player.min.js CHANGED
@@ -1 +1 @@
1
- if(typeof fv_flowplayer_conf!="undefined"){try{if(typeof window.localStorage=="object"&&typeof window.localStorage.volume!="undefined"){delete fv_flowplayer_conf.volume}}catch(e){}flowplayer.conf=fv_flowplayer_conf;flowplayer.conf.fullscreen=false;flowplayer.conf.chromecast=false;flowplayer.conf.embed=false;flowplayer.conf.share=false;flowplayer.conf.analytics=false;if(typeof fv_flowplayer_conf.disable_localstorage!="undefined"){flowplayer.conf.storage={}}try{flowplayer.conf.key=atob(flowplayer.conf.key)}catch(e){}if(!flowplayer.support.android&&flowplayer.conf.dacast_hlsjs){function FVAbrController(hls){this.hls=hls;this.nextAutoLevel=3}FVAbrController.prototype.nextAutoLevel=function(nextLevel){this.nextAutoLevel=nextLevel};FVAbrController.prototype.destroy=function(){};flowplayer.conf.hlsjs={startLevel:-1,abrController:FVAbrController}}function parseIOSVersion(UA){var e=/iP(ad|hone)(; CPU)? OS (\d+_\d)/.exec(UA);if(e&&e.length>1){return parseFloat(e[e.length-1].replace("_","."),10)}return 0}if(flowplayer.support.iOS&&flowplayer.support.iOS.chrome&&flowplayer.support.iOS.version==0){flowplayer.support.iOS.version=parseIOSVersion(navigator.userAgent)}if(flowplayer.support.iOS&&parseInt(flowplayer.support.iOS.version)>=13||!flowplayer.support.iOS&&flowplayer.support.browser.safari&&parseInt(flowplayer.support.browser.version)>=8){flowplayer.conf.hlsjs.safari=true}flowplayer.support.fvmobile=!!(!flowplayer.support.firstframe||flowplayer.support.iOS||flowplayer.support.android);var fls=flowplayer.support;if(flowplayer.conf.mobile_native_fullscreen&&"ontouchstart"in window&&fls.fvmobile){flowplayer.conf.native_fullscreen=true}if("ontouchstart"in window){if(fls.android&&fls.android.version<4.4&&!(fls.browser.chrome&&fls.browser.version>54)){flowplayer.conf.native_fullscreen=true}if(fls.iOS&&(fv_player_in_iframe()||fls.iOS.version<7)){flowplayer.conf.native_fullscreen=true}}}if(typeof fv_flowplayer_translations!="undefined"){flowplayer.defaults.errors=fv_flowplayer_translations}var fv_player_did_autoplay=false;function fv_player_videos_parse(args,root){try{var videos=JSON.parse(args)}catch(e){return false}var regex=new RegExp("[\\?&]fv_flowplayer_mobile=([^&#]*)");var results=regex.exec(location.search);if((results!=null&&results[1]=="yes"||(jQuery(window).width()<=480||jQuery(window).height()<=480))&&(results==null||results[1]!="no")){var fv_fp_mobile=false;jQuery(videos.sources).each(function(k,v){if(v.mobile){videos.sources[k]=videos.sources[0];videos.sources[0]=v;fv_fp_mobile=true}if(fv_fp_mobile){jQuery(root).after('<p class="fv-flowplayer-mobile-switch">'+fv_flowplayer_translations.mobile_browser_detected_1+' <a href="'+document.URL+'?fv_flowplayer_mobile=no">'+fv_flowplayer_translations.mobile_browser_detected_2+"</a>.</p>")}})}root.trigger("fv_player_videos_parse",videos);return videos}function fv_player_in_iframe(){try{return window.self!==window.top}catch(e){return true}}jQuery(document).ready(function(){var loading_count=0;var loading=setInterval(function(){loading_count++;if(loading_count<1e3&&(window.fv_video_intelligence_conf&&!window.FV_Player_IMA||window.fv_vast_conf&&!window.FV_Player_IMA||window.fv_player_pro&&!window.FV_Flowplayer_Pro&&document.getElementById("fv_player_pro")!=fv_player_pro||window.fv_player_user_playlists&&!fv_player_user_playlists.is_loaded||window.FV_Player_JS_Loader_scripts_total&&window.FV_Player_JS_Loader_scripts_loaded<FV_Player_JS_Loader_scripts_total)){return}clearInterval(loading);fv_player_preload()},10)});function fv_escape_attr(text){var map={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return text.replace(/[&<>"']/g,function(m){return map[m]})}function fv_player_preload(){if(flowplayer.support.touch){jQuery(".fp-playlist-external.fv-playlist-design-2017").addClass("visible-captions")}flowplayer(function(api,root){if(localStorage.flowplayerTestStorage){delete localStorage.flowplayerTestStorage}root=jQuery(root);var fp_player=root.find(".fp-player");var splash_click=false;if(root.hasClass("fixed-controls")){root.find(".fp-controls").on("click",function(e){if(!api.loading&&!api.ready){e.preventDefault();e.stopPropagation();api.load()}})}if(!flowplayer.support.volume&&!flowplayer.support.autoplay){root.find(".fp-volume").hide()}if(root.data("volume")==0&&root.hasClass("no-controlbar")){root.find(".fp-volume").remove()}var playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]");if((!api.conf.playlist||api.conf.playlist.length==0)&&playlist.length&&playlist.find("a[data-item]").length>0){var items=[];playlist.find("a[data-item]").each(function(){if(parsed=fv_player_videos_parse(jQuery(this).attr("data-item"),root)){items.push(parsed)}else{jQuery(this).remove()}});api.conf.playlist=items;api.conf.clip=items[0]}else if(!api.conf.clip){api.conf.clip=fv_player_videos_parse(jQuery(root).attr("data-item"),root)}jQuery("a",playlist).on("click",function(e){e.preventDefault();splash_click=true;var $this=jQuery(this),playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]"),index=jQuery("a",playlist).index(this);$prev=$this.prev("a"),item=$this.data("item");if(location.href.match(/wp-admin/)&&$this.parents(".fv-player-editor-preview").length>0){fv_flowplayer_conf.current_video_to_edit=index;$this.parents(".fv-player-custom-video").find(".edit-video .fv-player-editor-button").trigger("click");return false}if($prev.length&&$this.is(":visible")&&!$prev.is(":visible")){$prev.trigger("click");return false}if(jQuery("#"+$this.parent().attr("rel")).hasClass("dynamic-playlist"))return;var playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]");fv_player_playlist_active(playlist,this);if(api){if(api.error){api.pause();api.error=api.loading=false;root.removeClass("is-error");root.find(".fp-message.fp-shown").remove()}if(!api.video||api.video.index==index)return;api.play(index)}var new_splash=item.splash;if(!new_splash){new_splash=$this.find("img").attr("src")}player_splash(root,fp_player,item,new_splash);var rect=root[0].getBoundingClientRect();if(rect.bottom-100<0){jQuery("html, body").animate({scrollTop:jQuery(root).offset().top-100},300)}});var playlist_external=jQuery("[rel="+root.attr("id")+"]");var playlist_progress=false;var splash_img=root.find(".fp-splash");var splash_text=root.find(".fv-fp-splash-text");function player_splash(root,fp_player,item,new_splash){var splash_img=root.find("img.fp-splash");if(new_splash){if(splash_img.length==0){splash_img=jQuery('<img class="fp-splash" />');fp_player.prepend(splash_img)}splash_img.attr("alt",item.fv_title?fv_escape_attr(item.fv_title):"video");splash_img.attr("src",new_splash)}else if(splash_img.length){splash_img.remove()}}api.bind("load",function(e,api,video){if(!api.conf.playlist.length){return}if(video.type.match(/^audio/)&&!splash_click){var anchor=playlist_external.find("a").eq(video.index);var item=anchor.data("item");var new_splash=item.splash;if(!new_splash){new_splash=anchor.find("img").attr("src")}player_splash(root,fp_player,item,new_splash)}splash_click=false});api.bind("ready",function(e,api,video){setTimeout(function(){if(video.index>-1){if(playlist_external.length>0){var playlist_item=jQuery("a",playlist_external).eq(video.index);fv_player_playlist_active(playlist_external,playlist_item);playlist_progress=playlist_item.find(".fvp-progress")}}},100);splash_img=root.find(".fp-splash");if(!video.is_audio_stream&&!video.type.match(/^audio/)){splash_img.remove();splash_text.remove()}});api.bind("unload",function(){jQuery(".fp-playlist-external .now-playing").remove();jQuery(".fp-playlist-external a").removeClass("is-active");var iframe=fp_player.find("iframe.fp-engine");if(iframe.length){iframe.after(splash_text);iframe.after(splash_img)}else{fp_player.prepend(splash_text);fp_player.prepend(splash_img)}playlist_progress=false});api.bind("progress",function(e,api,time){if(playlist_progress.length){api.playlist_thumbnail_progress(playlist_progress,api.video,time)}});api.bind("error-subtitles",function(){console.log("error-subtitles");fv_player_notice(root,fv_flowplayer_translations[8],2e3)});var playlist=jQuery(root).parent().find("div.fp-playlist-vertical[rel="+jQuery(root).attr("id")+"]");if(playlist.length){function check_size_and_all(args){var property=playlist.hasClass("fp-playlist-only-captions")?"height":"max-height";if(playlist.parents(".fp-playlist-text-wrapper").hasClass("is-fv-narrow")){property="max-height"}playlist.css(property,vertical_playlist_height());if(property=="max-height")playlist.css("height","auto")}check_size_and_all();jQuery(window).on("resize tabsactivate",function(){setTimeout(check_size_and_all,0)})}function vertical_playlist_height(args){var height=root.height();if(height==0)height=root.css("max-height");return height}api.show_status=function(type){var status="";["loading","ready","playing","paused","seeking"].every(function(v,k){if(api[v])status+=" "+v;return true});console.log("FV Player Status ("+type+")",status)};if(!window.fv_player_loaded){window.fv_player_loaded=true;setTimeout(function(){jQuery(document).trigger("fv_player_loaded");var event=new CustomEvent("fv_player_loaded",[]);document.dispatchEvent(event)},100)}setTimeout(function(){root.trigger("fv_player_loaded")},10)});if(window.self!=window.top&&!location.href.match(/fv_player_preview/)){embed_size();jQuery(window.self).resize(embed_size)}function embed_size(){jQuery(".flowplayer.fp-is-embed").each(function(){var root=jQuery(this);if(!root.hasClass("has-chapters")&&!root.hasClass("has-transcript")&&jQuery(".fp-playlist-external[rel="+root.attr("id")+"]").length==0){root.height(jQuery(window).height())}})}if(typeof fv_flowplayer_playlists!="undefined"){for(var i in fv_flowplayer_playlists){if(!fv_flowplayer_playlists.hasOwnProperty(i))continue;jQuery("#"+i).flowplayer({playlist:fv_flowplayer_playlists[i]})}}fv_player_load();fv_autoplay_exec();jQuery(document).ajaxComplete(function(){fv_player_load()});jQuery(window).on("hashchange",fv_autoplay_exec)}function fv_player_load(forced_el){if(forced_el&&forced_el.lenght>1){console.log("FV Player: Can't use fv_player_load with more than a single forced element!")}var load_players=forced_el,forced_api=false;if(!load_players)load_players=jQuery(".flowplayer");load_players.each(function(i,el){var root=jQuery(el);var api=root.data("flowplayer");if(api){if(forced_el)forced_api=api;return}if(forced_el){root.find(".fp-preload, .fvfp_admin_error").remove();if(root.attr("data-item-lazy")){root.attr("data-item",root.attr("data-item-lazy"));root.removeAttr("item-lazy")}else if(playlist=jQuery("[rel="+root.attr("id")+"]")){playlist.find("a[data-item-lazy]").each(function(k,v){v=jQuery(v);v.attr("data-item",v.attr("data-item-lazy"));v.removeAttr("data-item-lazy")})}}var conf=false;if(root.attr("data-item")){conf={clip:fv_player_videos_parse(root.attr("data-item"),root)}}else if(playlist=jQuery("[rel="+root.attr("id")+"]")){if(playlist.find("a[data-item]").length==0)return;var items=[];playlist.find("a[data-item]").each(function(){if(parsed=fv_player_videos_parse(jQuery(this).attr("data-item"),root)){items.push(parsed)}else{jQuery(this).remove()}});conf={playlist:items}}if(conf){conf=flowplayer.extend(conf,root.data());forced_api=flowplayer(root[0],conf);root.data("flowplayer",forced_api)}});jQuery(".fv-playlist-slider-wrapper").each(function(i,el){var items=jQuery(this).find("a");jQuery(this).find(".fp-playlist-external").css("width",items.outerWidth()*items.length)});if(typeof jQuery().tabs!="undefined"){jQuery("body").removeClass("fv_flowplayer_tabs_hide");jQuery(".fv_flowplayer_tabs_content").tabs()}if(forced_el&&forced_api){return forced_api}}function fv_player_playlist_active(playlist,item){if(playlist){jQuery("a",playlist).removeClass("is-active");jQuery(".now-playing").remove()}$playlist=jQuery(playlist);$item=jQuery(item);var scroll_parent=false;$item.addClass("is-active");var is_design_2014=$playlist.hasClass("fv-playlist-design-2014");if((is_design_2014&&$item.find("h4").length==0||!is_design_2014)&&$item.find(".now-playing").length==0)$item.prepend('<strong class="now-playing"><span>'+fv_flowplayer_translations.playlist_current+"</span></strong>");if(!$playlist.parent().find(".flowplayer").length){scroll_parent=true}if(($playlist.hasClass("fp-playlist-vertical")||$playlist.hasClass("fp-playlist-horizontal")&&$playlist.hasClass("is-audio"))&&!fullyVisibleY($item.get(0))){var $el=scroll_parent?$playlist.parent():$playlist;$el.animate({scrollTop:$el.scrollTop()+($item.position().top-$el.position().top)},750)}else if($playlist.hasClass("fp-playlist-horizontal")&&!fullyVisibleX($item.get(0))){var $el=scroll_parent?$playlist.parent():$playlist;$el.animate({scrollLeft:$el.scrollLeft()+($item.position().left-$el.position().left)},750)}function fullyVisibleY(el){var rect=el.getBoundingClientRect(),top=rect.top,height=rect.height,bottom=top+height,el=el.parentNode;do{rect=el.getBoundingClientRect();if(bottom<=rect.bottom===false)return false;if(top<=rect.top)return false;el=el.parentNode}while(el!=document.body);return bottom<=document.documentElement.clientHeight}function fullyVisibleX(el){var rect=el.getBoundingClientRect(),left=rect.left,width=rect.width,right=left+width,el=el.parentNode;do{rect=el.getBoundingClientRect();if(right<=rect.right===false)return false;if(left<=rect.left)return false;el=el.parentNode}while(el!=document.body);return right<=document.documentElement.clientWidth}}var fv_fp_date=new Date;var fv_fp_utime=fv_fp_date.getTime();function fv_parse_sharelink(src){src=src.replace("https?://[^./].","");var prefix="fvp_";if(src.match(/(youtube.com)/)){return prefix+src.match(/(?:v=)([A-Za-z0-9_-]*)/)[1]}else if(src.match(/(vimeo.com)|(youtu.be)/)){return prefix+src.match(/(?:\/)([^/]*$)/)[1]}else{var match=src.match(/(?:\/)([^/]*$)/);if(match){return prefix+match[1].match(/^[^.]*/)[0]}}return prefix+src}function fv_player_get_video_link_hash(api){var hash=fv_parse_sharelink(typeof api.video.sources_original!="undefined"&&typeof api.video.sources_original[0]!="undefined"?api.video.sources_original[0].src:api.video.sources[0].src);if(typeof api.video.id!="undefined"){hash=fv_parse_sharelink(api.video.id.toString())}return hash}function fv_player_time_hms(seconds){if(isNaN(seconds)){return NaN}var sec_num=parseInt(seconds,10);var hours=Math.floor(sec_num/3600);var minutes=Math.floor(sec_num/60)%60;var seconds=sec_num%60;if(hours){hours+="h"}else{hours=""}if(hours&&minutes<10){minutes="0"+minutes+"m"}else if(minutes){minutes+="m"}else{minutes=""}if((hours||minutes)&&seconds<10){seconds="0"+seconds}seconds+="s";var timeString=hours+minutes+seconds;return timeString}function fv_player_time_hms_ms(seconds){if(isNaN(seconds)){return NaN}seconds=parseFloat(seconds).toFixed(3);var miliseconds=(seconds+"").split(".");if(typeof miliseconds[1]!="undefined"&&miliseconds[1]>0){miliseconds=miliseconds[1]+"ms"}else{miliseconds=""}var timeString=fv_player_time_hms(seconds)+miliseconds;return timeString}function fv_player_time_seconds(time,duration){if(!time)return-1;var seconds=0;var match=time.match(/(\d+[a-z]{1,2})/g);match.forEach(function(item){if(item.endsWith("h")){seconds+=3600*parseInt(item)}else if(item.endsWith("m")){seconds+=60*parseInt(item)}else if(item.endsWith("s")&&!item.endsWith("ms")){seconds+=parseInt(item)}else if(item.endsWith("ms")){if(parseInt(item)){seconds+=parseInt(item)/1e3}}});return duration?Math.min(seconds,duration):seconds}function fv_autoplay_init(root,index,time,abStart,abEnd){if(fv_autoplay_exec_in_progress)return;fv_autoplay_exec_in_progress=true;var api=root.data("flowplayer");if(!api)return;var fTime=fv_player_time_seconds(time);abEnd=fv_player_time_seconds(abEnd);abStart=fv_player_time_seconds(abStart);if(root.parent().hasClass("ui-tabs-panel")){var tabId=root.parent().attr("id");jQuery("[aria-controls="+tabId+"] a").trigger("click")}if(!root.find(".fp-player").attr("class").match(/\bis-sticky/)){var offset=jQuery(root).offset().top-(jQuery(window).height()-jQuery(root).height())/2;window.scrollTo(0,offset);api.one("ready",function(){window.scrollTo(0,offset)})}if(root.hasClass("lightboxed")){setTimeout(function(){jQuery("[href=\\#"+root.attr("id")+"]").trigger("click")},0)}if(index){if(fv_player_video_link_autoplay_can(api,parseInt(index))){if(api.ready){fv_player_video_link_seek(api,fTime)}else{api.play(parseInt(index));api.one("ready",function(){fv_player_video_link_seek(api,fTime,abEnd,abStart)})}}else if(flowplayer.support.inlineVideo){api.one(api.playing?"progress":"ready",function(e,api){api.play(parseInt(index));api.one("ready",function(){fv_player_video_link_seek(api,fTime,abEnd,abStart)})});root.find(".fp-splash").attr("src",jQuery("[rel="+root.attr("id")+"] div").eq(index).find("img").attr("src"));if(!fv_player_in_iframe()){fv_player_notice(root,fv_flowplayer_translations[11],"progress")}}}else{if(api.ready){fv_player_video_link_seek(api,fTime)}else{if(fv_player_video_link_autoplay_can(api)){api.load()}else if(!fv_player_in_iframe()){fv_player_notice(root,fv_flowplayer_translations[11],"progress")}api.one("ready",function(){fv_player_video_link_seek(api,fTime,abEnd,abStart)})}}}function fv_player_video_link_seek(api,fTime,abEnd,abStart){fv_autoplay_exec_in_progress=false;var do_seek=setInterval(function(){if(api.loading)return;if(fTime>0||api.video.time>0){if(!!api.custom_seek){api.custom_seek(fTime)}else{api.seek(fTime)}}if(abEnd&&abStart)api.trigger("link-ab",[api,abStart,abEnd]);clearInterval(do_seek)},10)}var fv_autoplay_exec_in_progress=false;function fv_autoplay_exec(){var autoplay=true;if(typeof flowplayer!=="undefined"&&typeof fv_flowplayer_conf!="undefined"&&fv_flowplayer_conf.video_hash_links&&window.location.hash.substring(1).length){var aHash=window.location.hash.match(/\?t=/)?window.location.hash.substring(1).split("?t="):window.location.hash.substring(1).split(",");var hash=aHash[0];var time=aHash[1]===undefined?false:aHash[1];var abStart=aHash[2]===undefined?false:aHash[2];var abEnd=aHash[3]===undefined?false:aHash[3];jQuery(".flowplayer").each(function(){var root=jQuery(this);if(root.hasClass("lightbox-starter")){root=jQuery(root.attr("href"))}var api=root.data("flowplayer");if(!api)return;var playlist=typeof api.conf.playlist!=="undefined"&&api.conf.playlist.length>1?api.conf.playlist:[api.conf.clip];for(var item in playlist){if(!playlist.hasOwnProperty(item))continue;var id=typeof playlist[item].id!=="undefined"?fv_parse_sharelink(playlist[item].id.toString()):false;if(hash===id&&autoplay){console.log("fv_autoplay_exec for "+id,item);fv_autoplay_init(root,parseInt(item),time,abStart,abEnd);autoplay=false;return false}}for(var item in playlist){if(!playlist.hasOwnProperty(item))continue;var src=fv_parse_sharelink(playlist[item].sources[0].src);if(hash===src&&autoplay){console.log("fv_autoplay_exec for "+src,item);fv_autoplay_init(root,parseInt(item),time,abStart,abEnd);autoplay=false;return false}}})}if(autoplay&&flowplayer.support.firstframe){jQuery(".flowplayer[data-fvautoplay]").each(function(){var root=jQuery(this),api=root.data("flowplayer"),autoplay=root.attr("data-fvautoplay");if(!fv_player_did_autoplay&&autoplay){if((flowplayer.support.android||flowplayer.support.iOS)&&api&&api.conf.clip.sources[0].type=="video/youtube"){console.log("FV Player: Autoplay for YouTube not supported on Android and iOS");return}else{fv_player_did_autoplay=true;if(api.conf.playlist.length&&!isNaN(parseFloat(autoplay))&&isFinite(autoplay)){api.play(parseInt(autoplay))}else{api.load()}var play_icon=root.find(".fp-play").addClass("invisible"),control_bar=root.find(".fp-controls").addClass("invisible");api.one("progress",function(){play_icon.removeClass("invisible");control_bar.removeClass("invisible")});if(autoplay=="muted"){api.mute(true,true)}}}})}}function fv_player_video_link_autoplay_can(api,item){var video=item?api.conf.playlist[item]:api.conf.clip;if(video.sources[0].type=="video/youtube"&&(flowplayer.support.iOS||flowplayer.support.android)||fv_player_in_iframe())return false;return flowplayer.support.firstframe}function fv_player_notice(root,message,timeout){var notices=jQuery(".fvfp-notices",root);if(!notices.length){notices=jQuery('<div class="fvfp-notices">');jQuery(".fp-player",root).append(notices)}var notice=jQuery('<div class="fvfp-notice-content">'+message+"</div></div>");notices.append(notice);if(typeof timeout=="string"){var player=jQuery(root).data("flowplayer");player.on(timeout,function(){notice.fadeOut(100,function(){jQuery(this).remove()})})}if(timeout>0){setTimeout(function(){notice.fadeOut(2e3,function(){jQuery(this).remove()})},timeout)}return notice}var fv_player_clipboard=function(text,successCallback,errorCallback){try{fv_player_doCopy(text);successCallback()}catch(e){if(typeof errorCallback!="undefined")errorCallback(e)}};function fv_player_doCopy(text){var textarea=document.createElement("textarea");textarea.value=text;textarea.style.opacity=0;textarea.style.position="absolute";textarea.setAttribute("readonly",true);document.body.appendChild(textarea);var selected=document.getSelection().rangeCount>0?document.getSelection().getRangeAt(0):false;if(navigator.userAgent.match(/ipad|ipod|iphone/i)){var editable=textarea.contentEditable;textarea.contentEditable=true;var range=document.createRange();range.selectNodeContents(textarea);var sel=window.getSelection();sel.removeAllRanges();sel.addRange(range);textarea.setSelectionRange(0,999999);textarea.contentEditable=editable}else{textarea.select()}try{var result=document.execCommand("copy");if(selected){document.getSelection().removeAllRanges();document.getSelection().addRange(selected)}document.body.removeChild(textarea);return result}catch(err){throw new Error("Unsuccessfull")}}flowplayer(function(api,root){root=jQuery(root);if(typeof api.conf.disable_localstorage!="undefined"){return}var hlsjs;flowplayer.engine("hlsjs-lite").plugin(function(params){hlsjs=params.hls;hlsjs.on(Hls.Events.ERROR,function(event,data){if(data.type=="mediaError"&&data.details=="fragParsingError"&&data.fatal==true){hlsjs.destroy();api.trigger("error",[api,{code:3}]);setTimeout(function(){root.removeClass("is-seeking");root.addClass("is-paused")},0)}});if(flowplayer.support.browser.safari){hlsjs.on(Hls.Events.KEY_LOADED,function(event){if(event=="hlsKeyLoaded"){setTimeout(function(){if(api.loading){console.log("FV Player: Safari stuck loading HLS, resuming playback...");api.resume()}},0)}})}var pick_quality=flowplayer.conf.hd_streaming&&!flowplayer.support.fvmobile?720:false;if(jQuery(params.root).data("hd_streaming")==false)pick_quality=false;if(localStorage.FVPlayerHLSQuality)pick_quality=localStorage.FVPlayerHLSQuality;if(pick_quality){hlsjs.on(Hls.Events.MANIFEST_PARSED,function(_,data){var found=false;jQuery.each(data.levels,function(k,v){if(v.height==pick_quality)found=k});if(!localStorage.FVPlayerHLSQuality&&!found){jQuery.each(data.levels,function(k,v){if(v.height>found)found=k})}if(found){console.log("FV Player: Picked "+data.levels[found].height+"p quality");hlsjs.startLevel=found;hlsjs.currentLevel=found}})}});root=jQuery(root);var search=document.location.search;if(localStorage.FVPlayerDashQuality){if(!api.conf.dash)api.conf.dash={};api.conf.dash.initialVideoQuality="restore"}root.on("click",".fp-qsel-menu a",function(){if(api.engine.engineName=="hlsjs-lite"){var quality=jQuery(this).data("quality");if(quality==-1){localStorage.removeItem("FVPlayerHLSQuality")}else{var level=hlsjs.levels[quality];localStorage.FVPlayerHLSQuality=level.height}}});if(localStorage.FVPlayerHLSQuality){api.conf.hlsjs.startLevel=parseInt(localStorage.FVPlayerHLSQuality);api.conf.hlsjs.testBandwidth=false;api.conf.hlsjs.autoLevelEnabled=false}else if(flowplayer.conf.hd_streaming&&!flowplayer.support.fvmobile){api.conf.hlsjs.startLevel=3;api.conf.hlsjs.testBandwidth=false;api.conf.hlsjs.autoLevelEnabled=false}api.bind("quality",function(e,api,quality){if(api.engine.engineName=="dash"){if(quality==-1){localStorage.removeItem("FVPlayerDashQuality")}else if(bitrates[quality]){localStorage.FVPlayerDashQuality=bitrates[quality].height}}});var bitrates=[];var last_quality=-1;api.bind("ready",function(e,api){root.find(".fp-qsel-menu strong").text(fv_flowplayer_translations.quality);if(api.engine.engineName=="dash"){bitrates=api.engine.dash.getBitrateInfoListFor("video");if(localStorage.FVPlayerDashQuality&&api.conf.dash.initialVideoQuality){api.quality(api.conf.dash.initialVideoQuality)}quality_sort()}else if(api.engine.engineName=="hlsjs-lite"){root.addClass("is-loading");api.loading=true;api.one("progress",function(){if(api.loading){root.removeClass("is-loading");api.loading=false}});if(api.video.qualities&&api.video.qualities.length>2){var qswitch=-1;if(localStorage.FVPlayerHLSQuality){jQuery(api.video.qualities).each(function(k,v){if(v.value==localStorage.FVPlayerHLSQuality){qswitch=localStorage.FVPlayerHLSQuality;return false}})}else if(flowplayer.conf.hd_streaming&&!flowplayer.support.fvmobile){jQuery(api.video.qualities).each(function(k,v){var height=parseInt(v.label);if(height>0&&qswitch==-1&&height>=720&&height<=720){qswitch=v.value}})}qswitch=parseInt(qswitch);if(qswitch>-1){root.one("progress",function(){setTimeout(function(){api.quality(qswitch)})})}quality_sort()}}else if(api.video.sources_fvqs&&api.video.sources_fvqs.length>0&&api.video.src.match(/vimeo.*?\.mp4/)){setTimeout(quality_sort,0)}root.find("a[data-quality]").removeClass("is-current")});if(search.match(/dash_debug/)||search.match(/hls_debug/))var debug_log=jQuery('<div class="fv-debug" style="background: gray; color: white; top: 10%; position: absolute; z-index: 1000">').appendTo(root.find(".fp-player"));api.bind("ready progress",quality_process);api.bind("quality",function(){setTimeout(quality_process,0)});function quality_process(){if(api.engine.engineName=="dash"){var stream_info=bitrates[api.engine.dash.getQualityFor("video")];if(stream_info.qualityIndex!=last_quality){last_quality=stream_info.qualityIndex;quality_label(stream_info.qualityIndex,bitrates)}if(search.match(/dash_debug/))quality_debug(stream_info.width,stream_info.height,stream_info.bitrate)}else if(api.engine.engineName=="hlsjs-lite"){if(hlsjs.currentLevel!=last_quality){last_quality=hlsjs.currentLevel;quality_label(hlsjs.currentLevel,hlsjs.levels)}if(search.match(/hls_debug/)){var level=hlsjs.levels[hlsjs.currentLevel];if(level){quality_debug(level.width,level.height,level.bitrate)}}}}function quality_label(index,qualities){if(!qualities[index])return;var height=qualities[index].height,hd_limit=541,lowest=1e5;jQuery(qualities).each(function(k,v){if(v.height>=720&&v.height<1400)hd_limit=720;if(v.height<lowest)lowest=v.height;if(localStorage.FVPlayerHLSQuality==v.height){root.find("a[data-quality]").removeClass("fp-selected fp-color");root.find("a[data-quality="+k+"]").addClass("fp-selected fp-color")}});root.find("a[data-quality]").removeClass("is-current");root.find("a[data-quality="+index+"]").addClass("is-current");var label="SD";if(height>=360&&lowest<height)label="SD";if(height>=hd_limit)label="HD";if(height>=1400)label="4K";root.find(".fp-qsel").html(label)}function quality_debug(w,h,br){debug_log.html("Using "+w+"x"+h+" at "+Math.round(br/1024)+" kbps")}function quality_sort(){var menu=root.find(".fp-qsel-menu");menu.children().each(function(i,a){menu.prepend(a)});menu.children().each(function(i,a){if(/^NaNp/.test(jQuery(a).html())){var bitrate=jQuery(a).html().match(/\((.*?)\)/);if(bitrate&&typeof bitrate[1]!=="undefined"){jQuery(a).html(bitrate[1])}}else{jQuery(a).html(jQuery(a).html().replace(/\(.*?\)/,""))}});menu.prepend(menu.find("a[data-quality=-1]"));menu.prepend(menu.find("strong"))}});flowplayer(function(api,root){root=jQuery(root);var player_id=root.attr("id"),ad=false;if(root.data("end_popup_preview")){jQuery(document).ready(function(){api.trigger("finish",[api])})}function ad_height_check(){var count=0;var ad_height_check=setInterval(function(){var height=ad&&ad.find(".adsbygoogle").height();count++;if(count>20*10||height>0)clearInterval(ad_height_check);if(height>root.height()){ad.addClass("tall-ad")}},50)}function show_ad(){var ad_data=root.attr("data-ad");if(typeof ad_data!="undefined"&&ad_data.length){try{ad_data=JSON.parse(ad_data)}catch(e){return false}if(!ad&&!root.hasClass("is-cva")&&root.width()>=parseInt(ad_data.width)){var html=ad_data.html;html=html.replace("%random%",Math.random());ad=jQuery('<div id="'+player_id+'_ad" class="wpfp_custom_ad">'+html+"</div>");root.find(".fp-player").append(ad);ad_height_check();setTimeout(function(){if(root.find(".wpfp_custom_ad video").length){api.pause()}},500)}}}function show_popup(event){var popup_data=root.attr("data-popup");if(typeof popup_data!="undefined"&&popup_data.length){try{popup_data=JSON.parse(popup_data)}catch(e){return false}if((event=="finish"||popup_data.pause||popup_data.html.match(/fv-player-ppv-purchase-btn-wrapper/))&&root.find(".wpfp_custom_popup").length==0){root.addClass("is-popup-showing");root.find(".fp-player").append('<div id="'+player_id+'_custom_popup" class="wpfp_custom_popup">'+popup_data.html+"</div>")}}}api.bind("ready",function(e,api){if(ad.length==1){ad.remove();ad=false}if(!root.data("ad_show_after")){show_ad()}}).bind("progress",function(e,api,current){if(current>root.data("ad_show_after")){show_ad()}}).bind("finish",function(e,api){if(typeof api.video.index=="undefined"||api.video.index+1==api.conf.playlist.length){show_popup(e.type)}}).bind("pause",function(e,api){show_popup(e.type)}).bind("resume unload seek",function(e,api){if(root.hasClass("is-popup-showing")){root.find(".wpfp_custom_popup").remove();root.removeClass("is-popup-showing")}})});jQuery(document).on("click",".fv_fp_close",function(){var ad=jQuery(this).parents(".wpfp_custom_ad_content"),video=ad.find("video");ad.fadeOut();if(video.length)video[0].pause();return false});jQuery(document).on("focus",".fv_player_popup input[type=text], .fv_player_popup input[type=email], .fv_player_popup textarea",function(){var api=jQuery(this).parents(".flowplayer").data("flowplayer");if(api)api.disable(true)});jQuery(document).on("blur",".fv_player_popup input[type=text], .fv_player_popup input[type=email], .fv_player_popup textarea",function(){var api=jQuery(this).parents(".flowplayer").data("flowplayer");if(api)api.disable(false)});flowplayer(function(api,root){api.on("ready",function(e,api,video){api.one("progress",function(){jQuery(root).find(".fp-airplay").toggle(api.engine.engineName=="html5")})})});flowplayer(function(api,root){var root=jQuery(root),bean=flowplayer.bean,time=0,last=0,timer,event_name;if(typeof ga=="undefined"&&api.conf.fvanalytics&&typeof _gat=="undefined"&&typeof gtag=="undefined"){if(is_ga_4(api)){jQuery.getScript({url:"https://www.googletagmanager.com/gtag/js?id="+api.conf.fvanalytics,cache:true},function(){window.dataLayer=window.dataLayer||[];window.gtag=function(){window.dataLayer.push(arguments)};window.gtag("js",new Date);window.gtag("config",api.conf.fvanalytics)})}else{jQuery.getScript({url:"https://www.google-analytics.com/analytics.js",cache:true},function(){ga("create",api.conf.fvanalytics,"auto")})}}if(!window._paq&&api.conf.matomo_domain&&api.conf.matomo_site_id){var u="//"+api.conf.matomo_domain+"/";var _paq=window._paq=window._paq||[];_paq.push(["setTrackerUrl",u+"matomo.php"]);_paq.push(["setSiteId",api.conf.matomo_site_id]);var d=document,g=d.createElement("script"),s=d.getElementsByTagName("script")[0];g.type="text/javascript";g.async=true;g.src=u+"matomo.js";s.parentNode.insertBefore(g,s)}api.bind("progress",function(e,api,current){fv_track(e,api,current)}).bind("finish ready ",function(e,api){for(var j in fv_ga_events){if(!fv_ga_events.hasOwnProperty(j))continue;root.removeData("fv_track_"+fv_ga_events[j])}}).bind("error",function(e,api,error){setTimeout(function(){if(!api.error)return;var video=typeof api.video!="undefined"&&typeof api.video.src!="undefined"?api.video:false;if(!video&&typeof api.conf.clip!="undefined"&&typeof api.conf.clip.sources!="undefined"&&typeof api.conf.clip.sources[0]!="undefined"&&typeof api.conf.clip.sources[0].src!="undefined")video=api.conf.clip.sources[0];var name=fv_player_track_name(root,video);if(name&&!name.match(/\/\/vimeo.com\/\d/)){if(is_ga_4(api)){}else{fv_player_track(api,false,"Video "+(root.hasClass("is-cva")?"Ad ":"")+"error",error.message,name)}}},100)});api.bind("load unload",fv_track_seconds_played).bind("progress",function(e,api){if(!api.seeking){time+=last?+new Date-last:0;last=+new Date}if(!timer){timer=setTimeout(function(){timer=null;if(!is_ga_4(api)){fv_player_track(api,false,"Flowplayer heartbeat",api.engine.engineName+"/"+api.video.type,"Heartbeat",0)}},10*60*1e3)}}).bind("pause",function(){last=0});api.bind("shutdown",function(){bean.off(window,"unload",fv_track_seconds_played)});bean.on(window,"unload",fv_track_seconds_played);var fv_ga_events=is_ga_4(api)?["Play","25 Percent Played","50 Percent Played","75 Percent Played","100 Percent Played"]:["start","first quartile","second quartile","third quartile","complete"];function fv_track_seconds_played(e,api_not_needed,video){video=video||api.video;if(e.type==="load"){event_name=fv_player_track_name(root,video)}if(time){fv_player_track(api,false,"Video / Seconds played",api.engine.engineName+"/"+api.video.type,event_name,Math.round(time/1e3));time=0;if(timer){clearTimeout(timer);timer=null}}}function fv_track(e,api,data){var video=api.video,dur=video.duration,i=0;var name=fv_player_track_name(root,video);if(dur){if(data>19*dur/20)i=4;else if(data>3*dur/4)i=3;else if(data>dur/2)i=2;else if(data>dur/4)i=1}if(api.live)i=0;if(root.data("fv_track_"+fv_ga_events[i]))return;for(var j in fv_ga_events){if(!fv_ga_events.hasOwnProperty(j))continue;if(j==i)break;if(!root.data("fv_track_"+fv_ga_events[j]))return}root.trigger("fv_track_"+fv_ga_events[i].replace(/ /,"_"),[api,name]);root.data("fv_track_"+fv_ga_events[i],true);fv_player_track(api,false,"Video "+(root.hasClass("is-cva")?"Ad ":"")+fv_ga_events[i],api.engine.engineName+"/"+video.type,name)}api.get_time_played=function(){return time/1e3}});function is_ga_4(api){if(typeof api.conf.fvanalytics!="undefined"&&api.conf.fvanalytics&&api.conf.fvanalytics.startsWith("G-"))return true;return false}function fv_player_track(api,ga_id,event,engineType,name,value){if(typeof api!="object"){value=name;name=engineType;engineType=event;event=ga_id;ga_id=api;api=false}if(!ga_id)ga_id=flowplayer.conf.fvanalytics;if(typeof engineType=="undefined")engineType="Unknown engine";if(/fv_player_track_debug/.test(window.location.href))console.log("FV Player Track: "+event+" - "+engineType+" '"+name+"'",value);if(typeof gtag!="undefined"){if(is_ga_4(api)){gtag("event",event,{video_current_time:api.video.time,video_provider:engineType,video_duration:api.video.duration,value:value?value:1})}else{gtag("event",event,{event_category:engineType,event_label:name,value:value?value:1})}}else if(ga_id&&typeof ga!="undefined"){ga("create",ga_id,"auto",name,{allowLinker:true});ga("require","linker");if(value){ga("send","event",event,engineType,name,value)}else{ga("send","event",event,engineType,name)}}else if(ga_id&&typeof _gat!="undefined"){var tracker=_gat._getTracker(ga_id);if(typeof tracker._setAllowLinker=="undefined"){return}tracker._setAllowLinker(true);if(value){tracker._trackEvent(event,engineType,name,value)}else{tracker._trackEvent(event,engineType,name)}}if(flowplayer.conf.matomo_domain&&flowplayer.conf.matomo_site_id&&typeof _paq!="undefined"){if(value){_paq.push(["trackEvent",event,engineType,name,value])}else{_paq.push(["trackEvent",event,engineType,name])}}}function fv_player_track_name(root,video){var name=root.attr("title");if(!name&&typeof video.fv_title!="undefined")name=video.fv_title;if(!name&&typeof video.title!="undefined")name=video.title;if(!name&&typeof video.src!="undefined"){name=video.src.split("/").slice(-1)[0].replace(/\.(\w{3,4})(\?.*)?$/i,"");if(video.type.match(/mpegurl/))name=video.src.split("/").slice(-2)[0].replace(/\.(\w{3,4})(\?.*)?$/i,"")+"/"+name}return name}flowplayer(function(api,root){root=jQuery(root);var player=root.find(".fp-player"),had_no_volume=root.hasClass("no-volume"),had_fp_mute=root.hasClass("fp-mute"),had_fp_full=root.hasClass("fp-full"),buttons_count=0;function check_size(){var width=player.width()||root.width(),video_index=api.video.index?api.video.index:0;if(width>900){jQuery(".fp-subtitle",root).addClass("is-wide")}else{jQuery(".fp-subtitle",root).removeClass("is-wide")}root.toggleClass("is-tiny",width<400);root.toggleClass("is-small",width<600&&width>=400);var too_narrow=width<480+buttons_count*35;if(typeof api.fv_timeline_chapters_data!="undefined"&&typeof api.fv_timeline_chapters_data[video_index]!="undefined"){too_narrow=true}if(!had_fp_full){root.toggleClass("fp-full",root.hasClass("has-abloop")||too_narrow)}var size="";if(width<400)size="is-tiny";else if(width<600&&width>=400)size="is-small";root.trigger("fv-player-size",[size]);var el=player;if(root.parent().hasClass("fp-playlist-vertical-wrapper")||root.parent().hasClass("fp-playlist-text-wrapper"))el=root.parent();if(el.width()<=560){el.addClass("is-fv-narrow")}else{el.removeClass("is-fv-narrow")}if(width<=320){root.addClass("no-volume fp-mute")}else{if(!had_no_volume)root.removeClass("no-volume");if(!had_fp_mute)root.removeClass("fp-mute")}}check_size();jQuery(window).on("resize",check_size);api.on("ready fullscreen fullscreen-exit sticky sticky-exit",function(e){setTimeout(function(){buttons_count=root.find(".fp-controls > strong:visible").length+root.find(".fp-controls > .fp-icon:visible").length;check_size()},0)});api.on("unload pause finish error",function(){if(typeof checker!=="undefined")clearInterval(checker)})});jQuery(window).on("resize tabsactivate",function(){jQuery(".fp-playlist-external").each(function(){var playlist=jQuery(this);if(playlist.parent().width()>=900)playlist.addClass("is-wide");else playlist.removeClass("is-wide")})}).trigger("resize");flowplayer(function(api,root){api.bind("ready",function(){if(/Chrome/.test(navigator.userAgent)&&parseFloat(/Chrome\/(\d\d)/.exec(navigator.userAgent)[1],10)>54){if(api.video.subtitles){jQuery(root).addClass("chrome55fix-subtitles")}else{jQuery(root).addClass("chrome55fix")}}});root=jQuery(root);var image_src=root.css("background-image");if(image_src){image_src=image_src.replace(/url\((['"])?(.*?)\1\)/gi,"$2").split(",");if(!image_src||!image_src[0].match(/^(https?:)?\/\//))return;var image=new Image;image.src=image_src[0];var image_ratio=image.height/image.width;var player_ratio=root.height()/root.width();var ratio_diff=Math.abs(player_ratio-image_ratio);if(ratio_diff<.05){root.css("background-size","cover")}}});(function($){$(window).on("resize",function(){var iframe=$("iframe[id][src][height][width]");iframe.each(function(){if($(this).attr("id").match(/(fv_vimeo_)|(fv_ytplayer_)/)&&$(this).width()<=$(this).attr("width"))$(this).height($(this).width()*$(this).attr("height")/$(this).attr("width"))});var wistia=jQuery(".wistia_embed");wistia.each(function(){$(this).height($(this).width()*$(this).data("ratio"))})}).trigger("resize")})(jQuery);jQuery(document).on("tabsactivate",".fv_flowplayer_tabs_content",function(event,ui){var oldPlayer=jQuery(ui.oldPanel).find(".flowplayer").data("flowplayer");if(typeof oldPlayer!="undefined"){oldPlayer.pause()}var objPlayer=jQuery(".flowplayer",ui.newPanel);var api=objPlayer.data("flowplayer");api.load()});flowplayer(function(api,root){root=jQuery(root);var bean=flowplayer.bean;if(root.hasClass("is-audio")){bean.off(root[0],"mouseenter");bean.off(root[0],"mouseleave");root.removeClass("is-mouseout");root.addClass("fixed-controls").addClass("is-mouseover");api.on("error",function(e,api,error){jQuery(".fp-message",root).html(jQuery(".fp-message",root).html().replace(/video/,"audio"))});root.on("click",function(e){if(!api.ready){e.preventDefault();e.stopPropagation();api.load()}})}});flowplayer(function(api,root){if(!api.conf.fv_chromecast)return;if(!window["__onGCastApiAvailable"]){jQuery.getScript({url:"https://www.gstatic.com/cv/js/sender/v1/cast_sender.js",cache:true});window["__onGCastApiAvailable"]=function(loaded){if(!loaded)return;initialize()}}var conf=api.conf.chromecast||{},session,timer,trigger,bean=flowplayer.bean,common=flowplayer.common,waiting_for_seek=false;function initialize(){var applicationId,sessionRequest,apiConfig;applicationId=conf.applicationId||chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;sessionRequest=new chrome.cast.SessionRequest(applicationId);apiConfig=new chrome.cast.ApiConfig(sessionRequest,sessionListener,receiverListener);chrome.cast.initialize(apiConfig,onInitSuccess,onError)}function sessionListener(){}function receiverListener(ev){console.log("FV Player: Chromecast listener",ev);if(ev!==chrome.cast.ReceiverAvailability.AVAILABLE)return;flowplayer.conf.chromecast_available=true}function onInitSuccess(){}function onError(){console.log("chromecast onError")}function createUIElements(){var btnContainer=common.find(".fp-header",root)[0];if(!btnContainer)return;common.find(".fp-chromecast",btnContainer).forEach(common.removeNode);common.find(".fp-chromecast-engine",root).forEach(common.removeNode);trigger=common.createElement("a",{class:"fp-chromecast fp-icon",title:"Play on Cast device"});btnContainer.appendChild(trigger);var chromeCastEngine=common.createElement("div",{class:"fp-chromecast-engine"}),chromeCastStatus=common.createElement("p",{class:"fp-chromecast-engine-status"}),chromeCastIcon=common.createElement("p",{class:"fp-chromecast-engine-icon"});chromeCastEngine.appendChild(chromeCastIcon);chromeCastEngine.appendChild(chromeCastStatus);var engine=common.find(".fp-engine",root)[0];if(!engine)common.prepend(common.find(".fp-player",root)[0]||root,chromeCastEngine);else engine.parentNode.insertBefore(chromeCastEngine,engine)}function destroy(){clearInterval(timer);timer=null;api.release();common.toggleClass(root,"is-chromecast",false);common.toggleClass(trigger,"fp-active",false)}function get_media(){var media=false;var sources=api.video.sources_fvqs||api.video.sources;for(var i in sources){var type=sources[i].type;if(type=="video/mp4"||type=="video/fv-mp4"||type=="application/dash+xml"){media=sources[i];break}}if(!media){for(var i in sources){if(sources[i].type=="application/x-mpegurl"){media=sources[i];break}}}if(api.video.fvhkey&&!api.conf.hls_cast)return false;if(media){var top_quality=false,mp4_qualities=["fullhd","hd","md","sd"];for(var quality in mp4_qualities){var re=new RegExp("-"+mp4_qualities[quality]);for(var i in api.video.sources_fvqs){var source=api.video.sources_fvqs[i];if(source.src.match(re)&&source.type=="video/mp4"){top_quality=source;break}}if(top_quality){media=top_quality;break}}}return media}function load_media(){var media=get_media();if(!media){return false}var cast_subtitles=[];if(api.video.subtitles){api.video.subtitles.forEach(function(v,k){if(v.src.match(/\.srt/)){console.log("FV Player: Chromecast doesn't support SRT subtitles")}var subtitles=new chrome.cast.media.Track(k,chrome.cast.media.TrackType.TEXT);subtitles.trackContentId=v.src;subtitles.trackContentType="text/vtt";subtitles.subtype=chrome.cast.media.TextTrackType.SUBTITLES;subtitles.name=v.label;subtitles.language=v.srclang+"-"+k,subtitles.customData=null;cast_subtitles.push(subtitles)})}var mediaInfo=new chrome.cast.media.MediaInfo(media.src,media.type);mediaInfo.tracks=cast_subtitles;var request=new chrome.cast.media.LoadRequest(mediaInfo);if(!api.live){request.currentTime=api.video.time}clearInterval(timer);timer=false;session.loadMedia(request,onMediaDiscovered,function onMediaError(e){console.log("onMediaError",e)})}function onMediaDiscovered(chromecast){switch_tracks(chromecast);chromecast.addUpdateListener(function(alive){if(!session)return;timer=timer||setInterval(function(){api.trigger("progress",[api,chromecast.getEstimatedTime()]);chromecast.activeTrackIds.forEach(function(track_id){jQuery.each(chromecast.media.tracks,function(k,v){if(v.trackId==track_id&&v.type=="AUDIO"){var found=hilight_audio_track("data-audio",v.language);if(!found){hilight_audio_track("data-lang",v.language)}return false}})})},500);if(alive){common.toggleClass(root,"is-chromecast",true);common.toggleClass(trigger,"fp-active",true);api.hijack({pause:function(){console.log("hijacked pause!");chromecast.pause()},resume:function(){if(api.finished){clearInterval(timer);timer=null;api.release();load_media();return}chromecast.play()},seek:function(time){var req=new chrome.cast.media.SeekRequest;req.currentTime=time;chromecast.seek(req)}})}var playerState=chromecast.playerState;if(api.paused&&playerState===chrome.cast.media.PlayerState.PLAYING)api.trigger("resume",[api]);if(api.playing&&playerState===chrome.cast.media.PlayerState.PAUSED)api.trigger("pause",[api]);if(api.seeking&&playerState===chrome.cast.media.PlayerState.BUFFERING){waiting_for_seek=true}if(api.seeking&&playerState===chrome.cast.media.PlayerState.PLAYING&&waiting_for_seek){waiting_for_seek=false;api.trigger("seek",[api])}if(playerState==chrome.cast.media.PlayerState.IDLE&&chromecast.idleReason==chrome.cast.media.IdleReason.FINISHED){api.trigger("finish",[api])}common.toggleClass(root,"is-loading",playerState===chrome.cast.media.PlayerState.BUFFERING)})}api.bind("ready",function(e,api,video){if(session){if(get_media()){api.one("progress",function(e,api){api.release();api.pause();api.mute(false,true);load_media()});api.mute(true,true)}else{session.stop();session=null;destroy();jQuery(trigger).hide()}return}if(!flowplayer.conf.chromecast_available)return;if(get_media()){createUIElements();jQuery(trigger).show()}else{FV_Flowplayer_Pro.log("FV Player: Can't find media source suitable for Chromecast!");jQuery(trigger).hide()}});bean.on(root,"click",".fp-chromecast",function(ev){ev.preventDefault();if(session){api.trigger("pause",[api]);if(session.media[0].media){var seek=session.media[0].getEstimatedTime();setTimeout(function(){api.seek(seek)},0)}session.stop();session=null;destroy();return}if(api.playing)api.pause();chrome.cast.requestSession(function(s){jQuery(root).addClass("is-loading");session=s;var receiverName=session.receiver.friendlyName;common.html(common.find(".fp-chromecast-engine-status",root)[0],"Playing on device "+receiverName);load_media()},function(err){console.error("requestSession error",err)})});bean.on(root,"click",".fv-fp-hls-menu [data-audio], .fp-subtitle-menu [data-subtitle-index]",function(){if(session&&session.media[0].media){switch_tracks(session.media[0]);return false}});jQuery(window).on("unload",function(){if(session){session.stop()}});function hilight_audio_track(attr,chromecast_language){var audio_tracks_menu=jQuery(root).find(".fv-fp-hls-menu a"),found=false;audio_tracks_menu.each(function(k,el){if(jQuery(el).attr(attr)===chromecast_language){jQuery(el).addClass("fp-selected");found=true}else{jQuery(el).removeClass("fp-selected")}});return found}function switch_tracks(chromecast){console.log(chromecast.media.tracks);var audio=jQuery(root).find(".fv-fp-hls-menu [data-audio].fp-selected").data("audio"),audio_lang=jQuery(root).find(".fv-fp-hls-menu [data-audio].fp-selected").data("lang"),subtitle_index=jQuery(root).find(".fp-subtitle-menu [data-subtitle-index].fp-selected").data("subtitle-index"),subtitles=subtitle_index>-1?api.video.subtitles[subtitle_index].srclang:false;var audio_found=false,subtitles_found=false,tracks_selected=[];jQuery.each(chromecast.media.tracks,function(k,v){if(v.language==audio&&v.type=="AUDIO"){audio_found=v}if(v.language==subtitles+"-"+subtitle_index&&v.type=="TEXT"){subtitles_found=v}});if(!audio_found){jQuery.each(chromecast.media.tracks,function(k,v){if(v.language==audio_lang&&v.type=="AUDIO"){audio_found=v;return false}})}var debug_log="";if(audio_found){tracks_selected.push(audio_found.trackId);debug_log+=audio_found.language+" audio"}if(subtitles_found){tracks_selected.push(subtitles_found.trackId);if(debug_log)debug_log+=" ";debug_log+=subtitles_found.language+" subtitles"}if(tracks_selected){var request=new chrome.cast.media.EditTracksInfoRequest(tracks_selected);chromecast.editTracksInfo(request,function(){console.log("FV Player: Chromecast "+debug_log+" loaded")},function(){console.log("FV Player: Chromecast "+debug_log+" failed")})}}});jQuery(document).on("mfpClose",function(){if(typeof jQuery(".flowplayer").data("flowplayer")!="undefined")jQuery(".flowplayer").data("flowplayer").unload()});jQuery(document).on("click",".vc_tta-tab a",function(){var api=jQuery(".flowplayer.is-playing").data("flowplayer");if(api)api.pause()});flowplayer(function(api,root){root=jQuery(root);api.bind("ready",function(){setTimeout(function(){var video=jQuery("video",root);if(video.length>0){video.prop("autoplay",false)}},100);root.find("video.fp-engine").addClass("intrinsic-ignore")})});jQuery(".flowplayer").on("ready",function(e,api){if(/BB10/.test(navigator.userAgent)){api.fullscreen()}});var fv_flowplayer_safety_resize_arr=Array();function fv_flowplayer_safety_resize(){var fv_flowplayer_safety_resize_init=false;jQuery(".flowplayer").each(function(){if(!jQuery(this).is(":visible")||jQuery(this).hasClass("lightboxed")||jQuery(this).hasClass("lightbox-starter")||jQuery(this).hasClass("is-audio"))return;if(jQuery(this).width()<30||jQuery(this).height()<20){fv_flowplayer_safety_resize_init=true;var el=jQuery(this);while(jQuery(el).width()<30||jQuery(el).width()==jQuery(this).width()){if(jQuery(el).parent().length==0)break;el=jQuery(el).parent()}jQuery(this).width(jQuery(el).width());jQuery(this).height(parseInt(jQuery(this).width()*jQuery(this).attr("data-ratio")));fv_flowplayer_safety_resize_arr[jQuery(this).attr("id")]=el}});if(fv_flowplayer_safety_resize_init){jQuery(window).resize(function(){jQuery(".flowplayer").each(function(){if(jQuery(this).hasClass("lightboxed")||jQuery(this).hasClass("lightbox-starter"))return;if(fv_flowplayer_safety_resize_arr[jQuery(this).attr("id")]){jQuery(this).width(fv_flowplayer_safety_resize_arr[jQuery(this).attr("id")].width());jQuery(this).height(parseInt(jQuery(this).width()*jQuery(this).attr("data-ratio")))}})})}}if(typeof flowplayer.conf.safety_resize!="undefined"&&flowplayer.conf.safety_resize){jQuery(document).ready(function(){setTimeout(function(){fv_flowplayer_safety_resize()},10)})}var isIE11=!!navigator.userAgent.match(/Trident.*rv[ :]*11\./);if(isIE11){jQuery(document).ready(function(){jQuery(".fp-waiting").hide()});flowplayer(function(api,root){api.bind("load",function(e){jQuery(e.currentTarget).find(".fp-waiting").show()}).bind("beforeseek",function(e){jQuery(e.currentTarget).find(".fp-waiting").show()}).bind("progress",function(e){jQuery(e.currentTarget).find(".fp-waiting").hide()}).bind("seek",function(e){jQuery(e.currentTarget).find(".fp-waiting").hide()}).bind("fullscreen",function(e){jQuery("#wpadminbar").hide()}).bind("fullscreen-exit",function(e){jQuery("#wpadminbar").show()})})}if(flowplayer.support.browser&&flowplayer.support.browser.msie&&parseInt(flowplayer.support.browser.version,10)<9){jQuery(".flowplayer").each(function(){jQuery(this).css("width",jQuery(this).css("max-width"));jQuery(this).css("height",jQuery(this).css("max-height"))})}if(location.href.match(/elementor-preview=/)){console.log("FV Player: Elementor editor is active");setInterval(fv_player_load,1e3)}else if(location.href.match(/brizy-edit-iframe/)){console.log("FV Player: Brizy editor is active");setInterval(fv_player_load,1e3)}if(window.DELEGATE_NAMES){flowplayer(function(api,root){fv_player_notice(root,fv_flowplayer_translations.chrome_extension_disable_html5_autoplay)})}flowplayer(function(api,root){flowplayer.bean.off(root,"contextmenu")});if(location.href.match(/elementor-preview=/)){console.log("FV Player: Elementor editor is active");setInterval(fv_player_load,1e3)}flowplayer(function(player,root){root=jQuery(root);if(typeof root.data("fv-embed")=="undefined"||!root.data("fv-embed")||root.data("fv-embed")=="false")return;player.embedCode=function(){var video=player.video;var width=root.width();var height=root.height();height+=2;if(root.hasClass("has-chapters")||root.hasClass("has-transcript")){height+=300}if(jQuery(".fp-playlist-external[rel="+root.attr("id")+"]").length>0){height+=150+20}var link=root.data("fv-embed")+"#"+fv_player_get_video_link_hash(player);return'<iframe src="'+link+'" allowfullscreen width="'+width+'" height="'+height+'" frameborder="0" style="max-width:100%"></iframe>'}});jQuery(document).on("click",".flowplayer .embed-code-toggle",function(){var root=jQuery(this).closest(".flowplayer");if(typeof fv_player_editor_conf!="undefined"){fv_player_notice(root,fv_player_editor_translations.embed_notice,2e3);return false}var button=jQuery(this);var player=button.parents(".flowplayer");var api=player.data("flowplayer");if(typeof api.embedCode=="function"){player.find(".embed-code textarea").val(api.embedCode())}fv_player_clipboard(player.find(".embed-code textarea").val(),function(){fv_player_notice(player,fv_flowplayer_translations.embed_copied,2e3)},function(){button.parents(".fvp-share-bar").find(".embed-code").toggle();button.parents(".fvp-share-bar").toggleClass("visible")});return false});flowplayer(function(player,root){if(jQuery(root).data("fullscreen")==false){return}player.one("ready",function(e,api,video){if(jQuery(root).find(".fp-fullscreen").length==0){jQuery(root).find(".fp-header").append('<a class="fp-fullscreen fp-icon"></a>')}});var FS_ENTER="fullscreen",FS_EXIT="fullscreen-exit",FS_SUPPORT=flowplayer.support.fullscreen,win=window,scrollX,scrollY,bean=flowplayer.bean;player.fullscreen=function(flag){if(player.disabled)return;var video=common.find("video.fp-engine",root)[0];if(flowplayer.conf.native_fullscreen&&video&&flowplayer.support.iOS){player.trigger(FS_ENTER,[player]);bean.on(document,"webkitfullscreenchange.nativefullscreen",function(){if(document.webkitFullscreenElement!==video)return;bean.off(document,".nativefullscreen");bean.on(document,"webkitfullscreenchange.nativefullscreen",function(){if(document.webkitFullscreenElement)return;bean.off(document,".nativefullscreen");player.trigger(FS_EXIT,[player])})});video.webkitEnterFullScreen();bean.one(video,"webkitendfullscreen",function(){bean.off(document,"fullscreenchange.nativefullscreen");player.trigger(FS_EXIT,[player]);common.prop(video,"controls",true);common.prop(video,"controls",false)});return}var wrapper=jQuery(root).find(".fp-player")[0];if(flag===undefined)flag=!player.isFullscreen;if(flag){scrollY=win.scrollY;scrollX=win.scrollX}if(FS_SUPPORT){if(flag){["requestFullScreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen"].forEach(function(fName){if(typeof wrapper[fName]==="function"){wrapper[fName]({navigationUI:"hide"});if(fName==="webkitRequestFullScreen"&&!document.webkitFullscreenElement){wrapper[fName]()}}})}else{["exitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"].forEach(function(fName){if(typeof document[fName]==="function"){document[fName]()}})}}else{player.trigger(flag?FS_ENTER:FS_EXIT,[player])}return player};var lastClick,common=flowplayer.common;player.on("mousedown.fs",function(){if(+new Date-lastClick<150&&player.ready)player.fullscreen();lastClick=+new Date});player.on(FS_ENTER,function(){common.addClass(root,"is-fullscreen");common.toggleClass(root,"fp-minimal-fullscreen",common.hasClass(root,"fp-minimal"));common.removeClass(root,"fp-minimal");if(!FS_SUPPORT)common.css(root,"position","fixed");player.isFullscreen=true}).on(FS_EXIT,function(){var oldOpacity;common.toggleClass(root,"fp-minimal",common.hasClass(root,"fp-minimal-fullscreen"));common.removeClass(root,"fp-minimal-fullscreen");if(!FS_SUPPORT&&player.engine==="html5"){oldOpacity=root.css("opacity")||"";common.css(root,"opacity",0)}if(!FS_SUPPORT)common.css(root,"position","");common.removeClass(root,"is-fullscreen");if(!FS_SUPPORT&&player.engine==="html5")setTimeout(function(){root.css("opacity",oldOpacity)});player.isFullscreen=false;if(player.engine.engineName!="fvyoutube"){win.scrollTo(scrollX,scrollY)}}).on("unload",function(){if(player.isFullscreen)player.fullscreen()});player.on("shutdown",function(){FULL_PLAYER=null;common.removeNode(wrapper)})});flowplayer(function(api,root){root=jQuery(root);if(flowplayer.conf.wpadmin||jQuery(root).hasClass("is-audio"))return;var playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]"),playlist_with_fullscreen=playlist.hasClass("fp-playlist-season")||playlist.hasClass("fp-playlist-polaroid");fsforce=root.data("fsforce")==true;if(root.data("fullscreen")==false){return}if(flowplayer.conf.mobile_force_fullscreen&&flowplayer.support.fvmobile||!flowplayer.support.fullscreen&&fsforce||playlist_with_fullscreen){if(!flowplayer.support.fullscreen){api.bind("ready",function(){if(api.video.vr)return;api.fullscreen(true)})}root.on("click",function(){if(!api.ready||api.paused)api.fullscreen(true)});jQuery("[rel="+root.attr("id")+"] a").on("click",function(e){if(!api.isFullscreen){api.fullscreen();api.resume()}});api.on("resume",function(){if(api.video.vr)return;if(!api.isFullscreen)api.fullscreen()});api.on("finish",function(){if(api.conf.playlist.length==0||api.conf.playlist.length-1==api.video.index)api.fullscreen(false)}).on("fullscreen",function(a,api){root.addClass("forced-fullscreen")}).on("fullscreen-exit",function(a,api){api.pause();root.removeClass("forced-fullscreen")})}else if(fsforce){var position,unload=root.find(".fp-unload"),is_closing=false;api.isFakeFullscreen=false;unload.show();root.on("click",function(e){if(!api.ready&&e.target!=unload[0])api.fakeFullscreen(true)});unload.on("click",function(e){if(api.ready){api.fullscreen(false)}else if(api.loading){is_closing=true;api.one("resume",function(e){is_closing=false;api.pause()})}api.fakeFullscreen(false);return false});jQuery("[rel="+root.attr("id")+"] a").on("click",function(e){if(!api.isFakeFullscreen){api.fakeFullscreen();api.resume()}});api.on("resume",function(){if(!is_closing&&!api.isFakeFullscreen)api.fakeFullscreen()}).on("finish",function(){if(api.conf.playlist.length==0||api.conf.playlist.length-1==api.video.index)api.fakeFullscreen(false)}).on("fullscreen",function(a,api){root.removeClass("fake-fullscreen")}).on("fullscreen-exit",function(a,api){if(api.isFakeFullscreen)api.fakeFullscreen(true,true)}).on("unload",function(a,api){});api.fakeFullscreen=function(flag,force){if(!force&&(api.isFakeFullscreen==flag||api.disabled))return;if(position===undefined)position=root.css("position");if(flag===undefined)flag=!api.isFakeFullscreen;api.isFakeFullscreen=flag;api.trigger(flag?"fakefullscreen":"fakefullscreen-exit",[api]);root.toggleClass("is-fullscreen fake-fullscreen forced-fullscreen",flag);if(flag){root.css("position","fixed")}else{root.css("position",position)}}}if(flowplayer.support.android&&flowplayer.conf.mobile_landscape_fullscreen&&window.screen&&window.screen.orientation){api.on("fullscreen",function(a,api){if(typeof api.video.width!="undefined"&&typeof api.video.height!="undefined"&&(api.video.width!=0&&api.video.height!=0&&api.video.width<api.video.height)){screen.orientation.lock("portrait-primary")}else{screen.orientation.lock("landscape-primary")}})}});flowplayer(function(api,root){root=jQuery(root);var hlsjs,player,audioUXGroup,audioGroups,hls_audio_button,hls_audio_menu,mse=window.MediaSource||window.WebKitMediaSource;flowplayer.engine("hlsjs-lite").plugin(function(params){hlsjs=params.hls});api.bind("ready",function(e,api){removeAudioMenu();if(hlsjs&&api.video.type=="application/x-mpegurl"){parseAudioTracksHlsJs(hlsjs);createAudioMenu()}});api.one("progress",function(){if(api.engine.engineName=="html5"&&api.video.type=="application/x-mpegurl"){parseAudioTracksSafari();createAudioMenu()}});function getVideoTagAudioTracks(){var video=root.find("video");if(video.length&&video[0].audioTracks){return video[0].audioTracks}return[]}function hilightAudioTrack(audioTrack){if(!audioTrack.name)audioTrack.name=audioTrack.label;root.find(".fv-fp-hls-menu a").each(function(k,el){jQuery(el).toggleClass("fp-selected",jQuery(el).attr("data-audio")===audioTrack.name)})}function createAudioMenu(){if(!audioUXGroup||audioUXGroup.length<2){return}hls_audio_button=jQuery('<strong class="fv-fp-hls">'+fv_flowplayer_translations.audio_button+"</strong>");hls_audio_menu=jQuery('<div class="fp-menu fv-fp-hls-menu"></div>').insertAfter(root.find(".fp-controls"));hls_audio_menu.append("<strong>"+fv_flowplayer_translations.audio_menu+"</strong>");audioUXGroup.forEach(function(audioTrack){hls_audio_menu.append('<a data-audio="'+audioTrack.name+'" data-lang="'+audioTrack.lang+'">'+audioTrack.name+"</a>")});hls_audio_button.insertAfter(root.find(".fp-controls .fp-volume")).on("click",function(e){e.preventDefault();e.stopPropagation();if(hls_audio_menu.hasClass("fp-active")){api.hideMenu(hls_audio_menu[0])}else{root.click();api.showMenu(hls_audio_menu[0])}});jQuery("a",hls_audio_menu).on("click",function(e){var adata=e.target.getAttribute("data-audio");if(hlsjs){var gid=hlsjs.audioTracks[hlsjs.audioTrack].groupId;var atrack=hlsjs.audioTracks.filter(function(at){return at.groupId===gid&&(at.name===adata||at.lang===adata)})[0];hlsjs.audioTrack=atrack.id;hilightAudioTrack(atrack)}else{var tracks=getVideoTagAudioTracks();for(var i in tracks){if(!tracks.hasOwnProperty(i))continue;if(tracks[i].label==adata){tracks[i].enabled=true;hilightAudioTrack(tracks[i])}}}});if(hlsjs){hilightAudioTrack(hlsjs.audioTracks[hlsjs.audioTrack])}else{var tracks=getVideoTagAudioTracks();for(var i in tracks){if(!tracks.hasOwnProperty(i))continue;if(tracks[i].enabled){hilightAudioTrack(tracks[i])}}}}function removeAudioMenu(){jQuery(hls_audio_menu).remove();jQuery(hls_audio_button).remove()}function parseAudioTracksHlsJs(data){audioGroups=[];audioUXGroup=[];data.levels.forEach(function(level){var agroup=level.attrs.AUDIO;if(agroup&&audioGroups.indexOf(agroup)<0){audioGroups.push(agroup)}if(audioGroups.length){audioUXGroup=data.audioTracks.filter(function(audioTrack){return audioTrack.groupId===audioGroups[0]})}})}function parseAudioTracksSafari(){audioGroups=[];audioUXGroup=[];var tracks=getVideoTagAudioTracks();for(var i in tracks){if(!tracks.hasOwnProperty(i))continue;audioUXGroup.push({id:tracks[i].id,name:tracks[i].label})}}});flowplayer(function(api,root){var store_engine_pos=-1;var store_engine=false;api.on("error",function(e,api,err){if(err.code!=4||api.engine.engineName!="hlsjs")return;console.log("FV Player: HLSJS failed to play the video, switching to Flash HLS");api.error=api.loading=false;jQuery(root).removeClass("is-error");jQuery(flowplayer.engines).each(function(k,v){if(flowplayer.engines[k].engineName=="hlsjs"){store_engine_pos=k;store_engine=flowplayer.engines[k];delete flowplayer.engines[k]}});var index=typeof api.video.index!="undefined"?api.video.index:0;var video=index>0?api.conf.playlist[index].sources:api.conf.clip.sources;video.index=index;api.load({sources:video});api.bind("unload error",function(){flowplayer.engines[store_engine_pos]=store_engine})})});flowplayer(function(api,root){var initialDelay=30,continueDelay=10,useDelay=initialDelay,retryLabel=fv_flowplayer_translations.live_stream_retry,timer;api.clearLiveStreamCountdown=function(){if(timer){clearInterval(timer);api.error=api.loading=false;jQuery(root).removeClass("is-error");jQuery(root).find(".fp-message.fp-shown").remove();api.unload()}};api.conf.flashls={manifestloadmaxretry:2};api.on("ready",function(){useDelay=initialDelay;retryLabel=fv_flowplayer_translations.live_stream_retry}).on("progress",function(){useDelay=continueDelay;retryLabel=fv_flowplayer_translations.live_stream_continue;clearInterval(timer)});api.on("error",function(e,api,err){setTimeout(function(){if(!api.conf.clip.live&&!api.conf.live&&!(err.video&&err.video.src.match(/\/\/vimeo.com\/event\//)))return;var delay=useDelay;if(api.conf.clip.streaming_time){delay=api.conf.clip.streaming_time-Math.floor(Date.now()/1e3)}else if(api.conf.clip.live_starts_in){delay=api.conf.clip.live_starts_in}var startLabel=fv_flowplayer_translations.live_stream_starting.replace(/%d/,secondsToDhms(delay));retryLabel=retryLabel.replace(/%d/,secondsToDhms(delay));var message=api.conf.clip.live_starts_in?startLabel:retryLabel;clearInterval(timer);if(err.code===1||err.code===2||err.code===4){root.className+=" is-offline";if(flowplayer.support.flashVideo){api.one("flashdisabled",function(){root.querySelector(".fp-flash-disabled").style.display="none"})}var messageElement=root.querySelector(".fp-ui .fp-message");messageElement.innerHTML=message;var reload_delay=delay>300?300:delay;timer=setInterval(function(){reload_delay-=1;delay-=1;if(reload_delay>0&&messageElement){messageElement.querySelector("span").innerHTML=secondsToDhms(delay)}else{clearInterval(timer);if(!api.error){return}api.error=api.loading=false;messageElement=root.querySelector(".fp-ui .fp-message");if(messageElement){root.querySelector(".fp-ui").removeChild(messageElement)}root.className=root.className.replace(/\bis-(error|offline)\b/g,"");api.load()}},1e3)}},1)});function secondsToDhms(seconds){seconds=Number(seconds);var d=Math.floor(seconds/(3600*24));var h=Math.floor(seconds%(3600*24)/3600);var m=Math.floor(seconds%3600/60);var s=Math.floor(seconds%60);var t=fv_flowplayer_translations;var output=d>0?d==1?t.duration_1_day.replace(/%s/,d):t.duration_n_days.replace(/%s/,d):"";if(output&&h>0)output+=", ";output+=h>0?h==1?t.duration_1_hour.replace(/%s/,h):t.duration_n_hours.replace(/%s/,h):"";if(output&&m>0)output+=", ";output+=m>0?m==1?t.duration_1_minute.replace(/%s/,m):t.duration_n_minutes.replace(/%s/,m):"";if(output&&s>0)output+=t.and;output+=s>0?s==1?t.duration_1_second.replace(/%s/,s):t.duration_n_seconds.replace(/%s/,s):"";return output}});flowplayer(function(api,root){root=jQuery(root);var hlsjs;flowplayer.engine("hlsjs-lite").plugin(function(params){hlsjs=params.hls});api.on("ready",function(e,api){if(hlsjs&&api.conf.playlist.length&&api.engine.engineName!="hlsjs-lite"){hlsjs.destroy()}})});flowplayer(function(api,root){if(!flowplayer.support.browser.safari&&!flowplayer.support.iOS)return;root=jQuery(root);var video_tag=false,did_start_playing=false,are_waiting_already=0;api.on("ready",function(e,api,video){are_waiting_already=0;did_start_playing=false;if(api.engine.engineName=="html5"&&video.src.match(/\?/)){video_tag=root.find("video");if(!video_tag.data("fv-ios-recovery")){video_tag.on("waiting",wait_for_stalled);video_tag.data("fv-ios-recovery",true)}api.one("progress",function(){did_start_playing=true})}});api.bind("beforeseek",wait_for_stalled);function debug(e){console.log("FV Player: iOS video element: "+e.type)}function wait_for_stalled(){if(!did_start_playing){return}if(video_tag&&api.engine.engineName=="html5"){are_waiting_already++;if(are_waiting_already>1){if(are_waiting_already>3){console.log("FV Player: iOS video element needs a push, triggering 'stalled'");video_tag.trigger("stalled")}return}console.log("FV Player: iOS video element will trigger error after 'stalled' arrives");video_tag.one("stalled",function(){var time=api.video.time;if(api.video.type.match(/video\//)){console.log("FV Player: Running check of video file...");var test_video=document.createElement("video");test_video.src=api.video.src;test_video.onloadedmetadata=function(){are_waiting_already=0;console.log("FV Player: Video link works")};test_video.onerror=function(){console.log("FV Player: Video link issue!");if(are_waiting_already>0){api.trigger("error",[api,{code:4,video:api.video}])}};return}setTimeout(function(){console.log(api.video.time,time);if(api.video.time!=time){console.log("FV Player: iOS video element continues playing, no need for error");return}if(api.paused){console.log("FV Player: iOS video element paused, no need for error");return}api.trigger("error",[api,{code:4,video:api.video}])},5e3)})}}});!function(e){var n=!1;if("function"==typeof define&&define.amd&&(define(e),n=!0),"object"==typeof exports&&(module.exports=e(),n=!0),!n){var o=window.Cookies,t=window.Cookies=e();t.noConflict=function(){return window.Cookies=o,t}}}(function(){function e(){for(var e=0,n={};e<arguments.length;e++){var o=arguments[e];for(var t in o)n[t]=o[t]}return n}function n(o){function t(n,r,i){var c;if("undefined"!=typeof document){if(arguments.length>1){if("number"==typeof(i=e({path:"/"},t.defaults,i)).expires){var a=new Date;a.setMilliseconds(a.getMilliseconds()+864e5*i.expires),i.expires=a}i.expires=i.expires?i.expires.toUTCString():"";try{c=JSON.stringify(r),/^[\{\[]/.test(c)&&(r=c)}catch(e){}r=o.write?o.write(r,n):encodeURIComponent(r+"").replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),n=(n=(n=encodeURIComponent(n+"")).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent)).replace(/[\(\)]/g,escape);var s="";for(var f in i)i[f]&&(s+="; "+f,!0!==i[f]&&(s+="="+i[f]));return document.cookie=n+"="+r+s}n||(c={});for(var p=document.cookie?document.cookie.split("; "):[],d=/(%[0-9A-Z]{2})+/g,u=0;u<p.length;u++){var l=p[u].split("="),C=l.slice(1).join("=");this.json||'"'!==C.charAt(0)||(C=C.slice(1,-1));try{var m=l[0].replace(d,decodeURIComponent);if(C=o.read?o.read(C,m):o(C,m)||C.replace(d,decodeURIComponent),this.json)try{C=JSON.parse(C)}catch(e){}if(n===m){c=C;break}n||(c[m]=C)}catch(e){}}return c}}return t.set=t,t.get=function(e){return t.call(t,e)},t.getJSON=function(){return t.apply({json:!0},[].slice.call(arguments))},t.defaults={},t.remove=function(n,o){t(n,"",e(o,{expires:-1}))},t.withConverter=n,t}return n(function(){})});flowplayer.bean.off(document,"keydown.fp");flowplayer(function(api,root){var bean=flowplayer.bean;if(!api.conf.keyboard)return;bean.on(root,"mouseenter mouseleave",function(e){fv_player_focused=!api.disabled&&e.type=="mouseover"?api:0;if(fv_player_focused)fv_player_focusedRoot=root});api.bind("ready",function(e,api,video){if(video.subtitles&&video.subtitles.length>0){var help=jQuery(root).find(".fp-help").html();help+='<div class="fp-help-section fp-help-subtitles"><p><em>c</em>cycle through subtitles</p></div>';jQuery(root).find(".fp-help").html(help)}else{jQuery(root).find(".fp-help-subtitles").remove()}})});flowplayer.bean.on(document,"keydown.fp",function(e){if(typeof fv_player_focused=="undefined")return;var api=fv_player_focused,focusedRoot=api?fv_player_focusedRoot:false,common=flowplayer.common;var el=api&&!api.disabled?api:0,metaKeyPressed=e.ctrlKey||e.metaKey||e.altKey,key=e.which,conf=el&&el.conf;if(common.hasClass(focusedRoot,"no-controlbar")||common.hasClass(focusedRoot,"is-cva"))return;if(!el||!conf.keyboard||el.disabled)return;if([63,187,191].indexOf(key)!=-1){common.toggleClass(focusedRoot,"is-help");return false}if(key==27&&common.hasClass(focusedRoot,"is-help")){common.toggleClass(focusedRoot,"is-help");return false}if(!metaKeyPressed&&el.ready){e.preventDefault();if(e.shiftKey){if(key==39)el.speed(true);else if(key==37)el.speed(false);else if(key==78)el.next();else if(key==80)el.prev();return}if(key<58&&key>47)return el.seekTo(key-48);switch(key){case 38:case 75:el.volume(el.volumeLevel+.15);break;case 40:case 74:el.volume(el.volumeLevel-.15);break;case 39:case 76:el.seeking=true;el.seek(api.video.time+5);break;case 37:case 72:el.seeking=true;el.seek(api.video.time-5);break;case 190:el.seekTo();break;case 32:el.toggle();break;case 70:if(conf.fullscreen)el.fullscreen();break;case 77:el.mute();break;case 81:el.unload();break;case 67:if(!api.video.subtitles||api.video.subtitles.length==0)break;var current_subtitles=jQuery(focusedRoot).find(".fp-dropdown li.active[data-subtitle-index]").data("subtitle-index");if(typeof current_subtitles=="undefined")current_subtitles=-1;current_subtitles++;if(current_subtitles>api.video.subtitles.length-1){current_subtitles=-1}api.trigger("fv-subtitles-switched");if(current_subtitles>-1){el.loadSubtitles(current_subtitles);fv_player_notice(focusedRoot,fv_flowplayer_translations.subtitles_switched+" "+api.video.subtitles[current_subtitles].label,"fv-subtitles-switched")}else{el.disableSubtitles();fv_player_notice(focusedRoot,fv_flowplayer_translations.subtitles_disabled,"fv-subtitles-switched")}break}}});flowplayer(function(api,root){root=jQuery(root);if(window.learndash_video_data&&learndash_video_data.videos_found_provider=="local"&&root.closest("[data-video-progression=true]").length){LearnDash_disable_assets(true);LearnDash_watchPlayers();api.on("finish",function(e,api,time){window.LearnDash_disable_assets(false)})}});flowplayer(function(api,root){api.bind("load",function(e,api,data){var player=jQuery(e.currentTarget);if(player.data("live")){var live_check=setTimeout(function(){player.find(".fp-ui").append('<div class="fp-message">'+fv_flowplayer_translations.live_stream_failed+"</div>");player.addClass("is-error")},1e4);jQuery(e.currentTarget).data("live_check",live_check)}}).bind("ready",function(e,api,data){clearInterval(jQuery(e.currentTarget).data("live_check"))}).bind("error",function(e,api,data){var player=jQuery(e.currentTarget);if(player.data("live")){player.find(".fp-message").html(fv_flowplayer_translations.live_stream_failed_2)}})});(function($){flowplayer(function(api,root){if(jQuery(root).hasClass("is-cva"))return;$(document).on("submit","#"+jQuery(root).attr("id")+" .mailchimp-form",function(e){e.preventDefault();$(".mailchimp-response",root).remove();$("input[type=submit]",root).attr("disabled","disabled").addClass("fv-form-loading");var data={action:"fv_wp_flowplayer_email_signup"};$("[name]",this).each(function(){data[this.name]=$(this).val()});$.post(fv_player.ajaxurl,data,function(response){response=JSON.parse(response);$('<div class="mailchimp-response"></div>').insertAfter(".mailchimp-form",root);if(response.text.match(/already subscribed/)){response.status="ERROR"}if(response.status==="OK"){$(".mailchimp-form input[type=text],.mailchimp-form input[type=email]",root).val("");$(".mailchimp-response",root).removeClass("is-fv-error").html(response.text);setTimeout(function(){$(".wpfp_custom_popup",root).fadeOut()},2e3)}else{$(".mailchimp-response",root).addClass("is-fv-error").html(response.text)}$("input[type=submit]",root).removeAttr("disabled").removeClass("fv-form-loading")})})})})(jQuery);function fv_flowplayer_mobile_switch(id){var regex=new RegExp("[\\?&]fv_flowplayer_mobile=([^&#]*)");var results=regex.exec(location.search);if((results!=null&&results[1]=="yes"||(jQuery(window).width()<=480||jQuery(window).height()<=480))&&(results==null||results[1]!="no")){var fv_fp_mobile=false;jQuery("#wpfp_"+id+" video source").each(function(){if(jQuery(this).attr("id")!="wpfp_"+id+"_mobile"){fv_fp_mobile=true;jQuery(this).remove()}});if(fv_fp_mobile){jQuery("#wpfp_"+id).after('<p class="fv-flowplayer-mobile-switch">'+fv_flowplayer_translations.mobile_browser_detected_1+' <a href="'+document.URL+'?fv_flowplayer_mobile=no">'+fv_flowplayer_translations.mobile_browser_detected_2+"</a>.</p>")}}}if(typeof fv_flowplayer_mobile_switch_array!="undefined"){for(var i in fv_flowplayer_mobile_switch_array){if(!fv_flowplayer_mobile_switch_array.hasOwnProperty(i))continue;fv_flowplayer_mobile_switch(i)}}flowplayer(function(api,root){if(!flowplayer.support.touch)return;jQuery.fn.fv_single_double_click=function(single_click_callback,double_click_callback,timeout){return this.each(function(){var clicks=0,self=this;jQuery(this).on("click",function(event){clicks++;if(clicks==1){setTimeout(function(){if(clicks==1){single_click_callback.call(self,event)}else{double_click_callback.call(self,event)}clicks=0},timeout||300)}})})};root=jQuery(root);var left=jQuery('<div class="fv-fp-tap-left"><span>-10s</span></div>'),right=jQuery('<div class="fv-fp-tap-right"><span>+10s</span></div>');left.fv_single_double_click(function(){api.toggle()},function(e){maybe_seek(e,left,api.ready?api.video.time-10:false)});right.fv_single_double_click(function(){api.toggle()},function(e){maybe_seek(e,right,api.ready?api.video.time+10:false)});root.find(".fp-ui").append(left).append(right);function maybe_seek(e,el,time){if(api.ready){api.seek(time);animation(el)}else{api.toggle()}e.preventDefault()}function animation(el){el.addClass("is-active");setTimeout(function(){el.removeClass("is-active")},500)}});flowplayer(function(api,root){root=jQuery(root);var instance_id=root.data("flowplayer-instance-id");flowplayer.audible_instance=-1;api.one("load",function(){setTimeout(function(){api.conf.splash=false},0)});api.on("ready",function(){var is_muted=root.data("volume")==0;if(!is_muted){flowplayer.audible_instance=instance_id}jQuery(".flowplayer[data-flowplayer-instance-id]").each(function(){var player=jQuery(this).data("flowplayer");var current_instance_id=jQuery(this).data("flowplayer-instance-id");if(flowplayer.audible_instance==-1||current_instance_id==flowplayer.audible_instance||current_instance_id==instance_id)return;if(player){if(player.ready){if(api.conf.multiple_playback){if(!is_muted){player.mute(true,true)}}else if(player.playing){player.pause()}}else{player.clearLiveStreamCountdown();player.unload()}}})}).on("mute",function(e,api,muted){if(!muted&&flowplayer.audible_instance!=instance_id){flowplayer(flowplayer.audible_instance).mute(true,true);flowplayer.audible_instance=instance_id}}).on("resume",function(){if(!api.conf.multiple_playback){jQuery(".flowplayer[data-flowplayer-instance-id]").each(function(){if(instance_id==jQuery(this).data("flowplayer-instance-id"))return;var player=jQuery(this).data("flowplayer");if(player&&player.playing){player.pause()}})}})});function fv_flowplayer_browser_ff_m4v(hash){if(flowplayer.support.browser&&flowplayer.support.browser.mozilla&&navigator.appVersion.indexOf("Win")!=-1){jQuery("#wpfp_"+hash).attr("data-engine","flash")}}if(typeof fv_flowplayer_browser_ff_m4v_array!="undefined"){for(var i in fv_flowplayer_browser_ff_m4v_array){if(!fv_flowplayer_browser_ff_m4v_array.hasOwnProperty(i))continue;fv_flowplayer_browser_ff_m4v(i)}}function fv_flowplayer_browser_chrome_fail(hash,sAttributes,sVideo,bAutobuffer){jQuery("#wpfp_"+hash).bind("error",function(e,api,error){if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&error!=null&&(error.code==3||error.code==4||error.code==5)){api.unload();jQuery("#wpfp_"+hash).attr("id","bad_wpfp_"+hash);jQuery("#bad_wpfp_"+hash).after('<div id="wpfp_'+hash+'" '+sAttributes+' data-engine="flash"></div>');jQuery("#wpfp_"+hash).flowplayer({playlist:[[{mp4:sVideo}]]});if(bAutobuffer){jQuery("#wpfp_"+hash).bind("ready",function(e,api){api.play()})}else{jQuery("#wpfp_"+hash).flowplayer().play(0)}jQuery("#bad_wpfp_"+hash).remove()}})}if(typeof fv_flowplayer_browser_chrome_fail_array!="undefined"){for(var i in fv_flowplayer_browser_chrome_fail_array){if(!fv_flowplayer_browser_chrome_fail_array.hasOwnProperty(i))continue;fv_flowplayer_browser_chrome_fail(i,fv_flowplayer_browser_chrome_fail_array[i]["attrs"],fv_flowplayer_browser_chrome_fail_array[i]["mp4"],fv_flowplayer_browser_chrome_fail_array[i]["auto_buffer"])}}function fv_flowplayer_browser_ie(hash){if(flowplayer.support.browser&&flowplayer.support.browser.msie&&parseInt(flowplayer.support.browser.version,10)>=9||!!navigator.userAgent.match(/Trident.*rv[ :]*11\./)){jQuery("#wpfp_"+hash).attr("data-engine","flash")}}if(typeof fv_flowplayer_browser_ie_array!="undefined"){for(var i in fv_flowplayer_browser_ie_array){if(!fv_flowplayer_browser_ie_array.hasOwnProperty(i))continue;fv_flowplayer_browser_ie(i)}}function fv_flowplayer_browser_chrome_mp4(hash){var match=window.navigator.appVersion.match(/Chrome\/(\d+)\./);if(match!=null){var chrome_ver=parseInt(match[1],10);if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&chrome_ver<28&&navigator.appVersion.indexOf("Win")!=-1||/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&chrome_ver<27&&navigator.appVersion.indexOf("Linux")!=-1&&navigator.userAgent.toLowerCase().indexOf("android")==-1){jQuery("#wpfp_"+hash).attr("data-engine","flash")}}}if(navigator.platform.indexOf("iPhone")!=-1||navigator.platform.indexOf("iPod")!=-1||navigator.platform.indexOf("iPad")!=-1||navigator.userAgent.toLowerCase().indexOf("android")!=-1){flowplayer(function(api,root){api.bind("error",function(e,api,error){if(error.code==10){jQuery(e.target).find(".fp-message").html(fv_flowplayer_translations.unsupported_format)}})})}jQuery(document).ready(function(){if(navigator.platform.indexOf("iPhone")!=-1||navigator.platform.indexOf("iPod")!=-1||navigator.platform.indexOf("iPad")!=-1){jQuery(window).trigger("load")}jQuery(".flowplayer").on("mouseleave",function(){jQuery(this).find(".fvp-share-bar").removeClass("visible");jQuery(this).find(".embed-code").hide()})});if(typeof flowplayer!=="undefined"){flowplayer(function(api,root){root=jQuery(root);var notice=false,hlsjs;flowplayer.engine("hlsjs-lite").plugin(function(params){hlsjs=params.hls});var playlist=api.conf.playlist.length?api.conf.playlist:[api.conf.clip];if(playlist[0]&&playlist[0].pending_encoding){show_notice(playlist[0])}api.on("load",function(e,api,video){if(video.pending_encoding){show_notice(video);if(hlsjs){hlsjs.destroy()}return false}remove_notice()});function show_notice(video){remove_notice();var title="Video is being processed",message="Please return later to see the actual video in this player.";if(video.pending_encoding_error){title="Video unavailable";message="There was an error in the video encoding."}else if(video.pending_encoding_progress){message+="<br /><br />("+video.pending_encoding_progress+" done)"}notice=jQuery('<div class="fv-player-encoder-video-processing-modal"><div><h2>'+title+"</h2><p>"+message+"</p></div></div");root.append(notice)}function remove_notice(){if(notice){notice.remove()}}})}if(!Date.now){Date.now=function(){return(new Date).getTime()}}(function($){var sendPositionsEvery=60,ajaxCall=null,maxCookieSize=2500,localStorageEnabled=null,cookiePositionsKeyName="video_positions",cookiePlaylistsKeyName="player_playlist_item",tempPositionCookieKeyName="video_positions_tmp",tempPlaylistsCookieKeyName="player_playlist_item_tmp",tempSawCookieKeyName="video_saw_tmp",playPositions=[],playlistIndexes=[],sawVideo=[],getSerialized=function(data){var serialized=JSON.stringify(data),dataSize=getTextByteSize(serialized);if(dataSize>maxCookieSize){while(dataSize>maxCookieSize){for(var i in data){if(!data.hasOwnProperty(i))continue;delete data[i];serialized=JSON.stringify(data);dataSize=getTextByteSize(serialized);break}}}return serialized},getVideoId=function(video){if(video.id){return video.id}var out=typeof video.sources_original!="undefined"&&typeof video.sources_original[0]!="undefined"?video.sources_original[0].src:video.sources[0].src;if(typeof video.sources_original=="undefined"||typeof video.sources_original[0]=="undefined"){out=removeAWSSignatures(out)}return out},getTextByteSize=function(txt){return encodeURIComponent(txt).length},getCookieKey=function(key){return localStorageEnabled?localStorage.getItem(key):Cookies.get(key)},setCookieKey=function(key,value){return localStorageEnabled?localStorage.setItem(key,value):Cookies.set(key,value)},removeCookieKey=function(key){if(localStorageEnabled){localStorage.removeItem(key)}{Cookies.remove(key)}},removeVideoPosition=function(e,api){if(api.video.sources){var video_id=getVideoId(api.video);playPositions[video_id]=0;sawVideo[video_id]=1}},removeAWSSignatures=function(videoURL){return videoURL.replace(/(X-Amz-Algorithm=[^&]+&?)/gm,"").replace(/(X-Amz-Credential=[^&]+&?)/gm,"").replace(/(X-Amz-Date=[^&]+&?)/gm,"").replace(/(X-Amz-Expires=[^&]+&?)/gm,"").replace(/(X-Amz-SignedHeaders=[^&]+&?)/gm,"").replace(/(X-Amz-Signature=[^&]+&?)/gm,"")},sendVideoPositions=function(async,callback){var beaconSupported="sendBeacon"in navigator;if(async!==true){async=false}if(!callback||typeof callback=="undefined"){callback=function(){}}postDataPositions=[];postDataPlaylists=[];for(var video_name in playPositions){if(!playPositions.hasOwnProperty(video_name))continue;postDataPositions.push({name:video_name,position:playPositions[video_name],saw:typeof sawVideo[video_name]!="undefined"?sawVideo[video_name]:false})}for(var player_id in playlistIndexes){if(!playlistIndexes.hasOwnProperty(player_id))continue;postDataPlaylists.push({player:player_id,item:playlistIndexes[player_id]})}if(!postDataPlaylists.length){removeCookieKey(tempPlaylistsCookieKeyName)}if(!postDataPositions.length){removeCookieKey(tempPositionCookieKeyName);removeCookieKey(tempSawCookieKeyName);return}if(flowplayer.conf.is_logged_in=="1"){if(beaconSupported){try{var temp_position_data={},temp_saw_data={},temp_playlist_data={};for(var i in postDataPositions){if(!postDataPositions.hasOwnProperty(i))continue;temp_position_data[postDataPositions[i].name]=postDataPositions[i].position;temp_saw_data[postDataPositions[i].name]=postDataPositions[i].saw}for(var i in postDataPlaylists){if(!postDataPlaylists.hasOwnProperty(i))continue;temp_playlist_data[postDataPlaylists[i].player]=postDataPlaylists[i].item}setCookieKey(tempPositionCookieKeyName,getSerialized(temp_position_data));setCookieKey(tempSawCookieKeyName,getSerialized(temp_saw_data));setCookieKey(tempPlaylistsCookieKeyName,getSerialized(temp_playlist_data))}catch(e){return}var fd=new FormData;fd.append("action","fv_wp_flowplayer_video_position_save");fd.append("videoTimes",encodeURIComponent(JSON.stringify(postDataPositions)));fd.append("playlistItems",encodeURIComponent(JSON.stringify(postDataPlaylists)));navigator.sendBeacon(fv_player.ajaxurl,fd);return false}else{return jQuery.ajax({type:"POST",async:async,url:fv_player.ajaxurl,complete:callback,data:{action:"fv_wp_flowplayer_video_position_save",videoTimes:postDataPositions,playlistItems:postDataPlaylists}})}}else{try{var data_positions=getCookieKey(cookiePositionsKeyName);var data_playlist_item=getCookieKey(cookiePlaylistsKeyName);if(data_positions&&typeof data_positions!=="undefined"){data_positions=JSON.parse(data_positions)}else{data_positions={}}if(data_playlist_item&&typeof data_playlist_item!=="undefined"){data_playlist_item=JSON.parse(data_playlist_item)}else{data_playlist_item={}}for(var i in postDataPositions){if(!postDataPositions.hasOwnProperty(i))continue;data_positions[postDataPositions[i].name]=postDataPositions[i].position}for(var i in postDataPlaylists){if(!postDataPlaylists.hasOwnProperty(i))continue;data_playlist_item[postDataPlaylists[i].player]=postDataPlaylists[i].item}var serialized_positions=JSON.stringify(data_positions),serialized_playlist_items=JSON.stringify(data_playlist_item),dataSize_postions=getTextByteSize(serialized_positions),dataSize_playlist_items=getTextByteSize(serialized_playlist_items);if(dataSize_postions>maxCookieSize){while(dataSize_postions>maxCookieSize){for(var i in data_positions){if(!data_positions.hasOwnProperty(i))continue;delete data_positions[i];serialized_positions=JSON.stringify(data_positions);dataSize_postions=getTextByteSize(serialized_positions);break}}}if(dataSize_playlist_items>maxCookieSize){while(dataSize_playlist_items>maxCookieSize){for(var i in data_positions){if(!data_playlist_item.hasOwnProperty(i))continue;delete data_playlist_item[i];serialized_playlist_items=JSON.stringify(data_playlist_item);dataSize_playlist_items=getTextByteSize(serialized_positions);break}}}setCookieKey(cookiePositionsKeyName,serialized_positions);setCookieKey(cookiePlaylistsKeyName,serialized_playlist_items)}catch(e){return}}return false};flowplayer(function(api,root){if(typeof api.conf.disable_localstorage!="undefined"){return}var $root=jQuery(root),enabled=flowplayer.conf.video_position_save_enable&&$root.data("save-position")!="false"||$root.data("save-position"),progressEventsCount=0,player_id=$root.data("player-id")?$root.data("player-id"):false,item_changed=false,seekIntoPosition=function(e,api){if(api.video&&api.video.live)return;var video_id=getVideoId(api.video),position=api.video.position;if(flowplayer.conf.is_logged_in!="1"){var data=getCookieKey(cookiePositionsKeyName);if(data&&typeof data!=="undefined"){try{data=JSON.parse(data);if(data[video_id]){position=data[video_id]}}catch(e){return}}}if(!!api.get_custom_end&&api.get_custom_end()<position){position=false}if(!!api.get_custom_start&&api.get_custom_start()>0){if(position<api.get_custom_start()){position=false}}api.bind("progress",storeVideoPosition);if(position){seek(position)}},storeVideoPosition=function(e,api){if(api.live){return}if(api.video.sources){var video_id=getVideoId(api.video),position=Math.round(api.video.time);playPositions[video_id]=position;if(api.conf.playlist.length>0){if(player_id)playlistIndexes[player_id]=api.video.index}if(progressEventsCount++>=sendPositionsEvery&&flowplayer.conf.closingPage){if(ajaxCall){ajaxCall.abort()}ajaxCall=sendVideoPositions(true,function(){ajaxCall=null});progressEventsCount=0}}},forceSavePosition=function(e,api){var inPlaylist=false;for(var i in api.conf.playlist){if(!api.conf.playlist.hasOwnProperty(i))continue;inPlaylist=true;break}if(inPlaylist&&!flowplayer.conf.closingPage){progressEventsCount=sendPositionsEvery+1;storeVideoPosition(e,api);sendVideoPositions()}},seek=function(position){if(!!api.custom_seek){api.custom_seek(position);return}var seek_count=0;var do_seek=setInterval(function(){if(++seek_count>20)clearInterval(do_seek);if(api.loading)return;api.seek(parseInt(position));clearInterval(do_seek)},10)},processTempData=function(temp_data_name,video_id){var data=getCookieKey(temp_data_name),output=false;if(data&&typeof data!=="undefined"){try{data=JSON.parse(data);if(typeof data[video_id]!="undefined"){output=data[video_id];delete data[video_id];var stillHasData=false;for(var i in data){if(!data.hasOwnProperty(i))continue;stillHasData=true;break}if(stillHasData){setCookieKey(temp_data_name,JSON.stringify(data))}else{removeCookieKey(temp_data_name)}}return output}catch(e){}}},restorePlaylistItem=function(e,api){if(typeof api=="undefined"||api.conf.playlist.length==0)return;var item_index=-1;if(player_id){if(flowplayer.conf.is_logged_in!="1"){var data=getCookieKey(cookiePlaylistsKeyName);if(data&&typeof data!=="undefined"){try{data=JSON.parse(data);if(data[player_id]){item_index=data[player_id]}}catch(e){return}}}else if(flowplayer.conf.is_logged_in=="1"){item_index=api.conf.playlist.length>0?processTempData(tempPlaylistsCookieKeyName,player_id):false}}if(item_index>=0&&!item_changed){api.play(item_index);item_changed=true}};if(!enabled)return;if(getCookieKey(tempPlaylistsCookieKeyName)){$root.removeData("playlist_start")}api.bind("finish",removeVideoPosition);api.one("progress",seekIntoPosition);api.bind("unload",function(){item_changed=false;api.one("ready",restorePlaylistItem)});api.one("ready",restorePlaylistItem);jQuery(".fp-ui",root).on("click",function(){restorePlaylistItem()});api.playlist_thumbnail_progress=function(el,video,position){if(!!api.get_custom_start&&api.get_custom_start(video)>0){position-=api.get_custom_start(video);if(position<0)position=0}var duration=video.duration;if(!!api.get_custom_duration&&api.get_custom_duration()>0){duration=api.get_custom_duration()}if(!duration){duration=el.data("duration")}if(!duration)return;var progress=100*position/duration;el.css("width",progress+"%")};if(flowplayer.conf.is_logged_in=="1"){var playlist=api.conf.playlist.length>0?api.conf.playlist:[api.conf.clip],playlist_external=jQuery("[rel="+jQuery(root).attr("id")+"]");for(var i in playlist){if(!playlist.hasOwnProperty(i))continue;var video_id=getVideoId(playlist[i]),position=processTempData(tempPositionCookieKeyName,video_id),saw=processTempData(tempSawCookieKeyName,video_id);if(position){if(api.conf.playlist.length){api.conf.playlist[i].sources[0].position=position;var playlist_progress=jQuery("a",playlist_external).eq(i).find(".fvp-progress");if(playlist_progress.length){api.playlist_thumbnail_progress(playlist_progress,api.conf.playlist[i],position)}}else{api.conf.clip.sources[0].position=position}}if(saw){if(api.conf.playlist.length){api.conf.playlist[i].sources[0].saw=true}else{api.conf.clip.sources[0].saw=true}}}}api.bind("finish",function(e,api){if(api.conf.playlist.length){api.conf.playlist[api.video.index].sources[0].saw=true}else{api.conf.clip.sources[0].saw=true}})});jQuery(window).on("beforeunload pagehide",function(){if(!flowplayer.conf.closingPage){flowplayer.conf.closingPage=true;sendVideoPositions()}});if(typeof fv_flowplayer_conf.disable_localstorage!="undefined"){localStorageEnabled=false}if(localStorageEnabled!==null){return localStorageEnabled}localStorageEnabled=true;try{localStorage.setItem("t","t");if(localStorage.getItem("t")!=="t"){localStorageEnabled=false}localStorage.removeItem("t")}catch(e){localStorageEnabled=false}})(jQuery);flowplayer(function(api,root){root=jQuery(root);if(api.conf.playlist.length==0)return;var real_videos=0;jQuery(api.conf.playlist).each(function(k,v){if(typeof v.click=="undefined"){real_videos++}});if(real_videos<2)return;var playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]");var playlist_button=jQuery('<strong class="fv-fp-list">Item 1.</strong>'),playlist_button_name=jQuery('<strong class="fv-fp-list-name">Item 1.</strong>'),playlist_menu=jQuery('<div class="fp-menu fv-fp-list-menu"></div>').insertAfter(root.find(".fp-controls"));var i=0,item_index=[],track_item=[];jQuery(api.conf.playlist).each(function(k,v){if(typeof v.click=="undefined"){var title=parse_title(playlist.find("h4").eq(i));playlist_menu.append('<a data-index="'+k+'">'+(i+1)+". "+title+"</a>");track_item[k]=title;item_index.push(k);i++}});function playlist_button_click(e){e.preventDefault();e.stopPropagation();if(playlist_menu.hasClass("fp-active")){api.hideMenu(playlist_menu[0])}else{root.trigger("click");api.showMenu(playlist_menu[0])}}playlist_button.insertAfter(root.find(".fp-controls .fp-volume")).on("click",playlist_button_click);playlist_button_name.insertAfter(playlist_button).on("click",playlist_button_click);jQuery("a",playlist_menu).on("click",function(){if(typeof api.conf.playlist[jQuery(this).data("index")-1]!="undefined"&&typeof api.conf.playlist[jQuery(this).data("index")-1].click!="undefined"){api.play(jQuery(this).data("index")-1)}else{api.play(jQuery(this).data("index"))}});api.on("ready",function(e,api,video){playlist_menu.find("a").removeClass("fp-selected");var thumb=playlist_menu.find("a[data-index="+video.index+"]");thumb.addClass("fp-selected");var label=fv_flowplayer_translations.playlist_item_no;label=label.replace(/%d/,item_index.indexOf(video.index)+1);label=label.replace(/%s/,parse_title(thumb.find("h4")));playlist_button.html(label);playlist_button_name.html(item_index.indexOf(video.index)+1+". "+track_item[video.index])});function parse_title(el){var tmp=el.clone();tmp.find("i.dur").remove();return tmp.text()}});flowplayer(function(api,root){root=jQuery(root);var playlist=api.conf.playlist,videoIndex;api.bind("load",function(e,api,video){videoIndex=video.index});api.bind("error",function(e,api,error){setTimeout(function(){if(playlist.length>0&&api.error==true){videoIndex=api.video.index;if(api.conf.video_checker=="1"&&playlist[videoIndex].video_checker&&playlist[videoIndex].video_checker.length>0){console.log("FV Player: Video checker message present, stopping auto-advance to next playlist item");return false}api.error=api.loading=false;root.removeClass("is-error");root.find(".fp-message.fp-shown").remove();videoIndex++;if(videoIndex>playlist.length-1){videoIndex=0}console.log("FV Player: Playlist item failure, auto-advancing to "+(videoIndex+1)+". item");api.play(videoIndex)}},1e3)})});flowplayer(function(api,root){root=jQuery(root);var original_prev,original_next,random_seed;if(!root.data("button-no-picture")&&!root.data("button-repeat")&&!root.data("button-rewind"))return;api.bind("ready",function(e,api){if(typeof original_next=="undefined"&&typeof original_prev=="undefined"){original_next=api.next;original_prev=api.prev}if(!api.video.type.match(/^audio/)&&root.data("button-no-picture")&&root.find(".fv-fp-no-picture").length==0){var button_no_picture=jQuery('<span class="fv-fp-no-picture"><svg viewBox="0 0 90 80" width="18px" height="18px" class="fvp-icon fvp-nopicture"><use xlink:href="#fvp-nopicture"></use></svg></span>');button_no_picture.insertAfter(root.find(".fp-controls .fp-volume")).on("click",function(e){e.preventDefault();e.stopPropagation();jQuery(".fp-engine",root).slideToggle(20);jQuery(this).toggleClass("is-active fp-color-fill")})}if(root.data("button-repeat")){if(api.conf.playlist.length>0&&root.find(".fv-fp-playlist").length==0){var t=fv_flowplayer_translations,playlist_button=jQuery('<strong class="fv-fp-playlist mode-normal"> <svg viewBox="0 0 80.333 80" width="18px" height="18px" class="fvp-icon fvp-replay-list"><title>'+t.playlist_replay_all+'</title><use xlink:href="#fvp-replay-list"></use></svg> <svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-shuffle"><title>'+t.playlist_shuffle+'</title><use xlink:href="#fvp-shuffle"></use></svg> <svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-replay-track"><title>'+t.playlist_replay_video+'</title><use xlink:href="#fvp-replay-track"></use></svg> <span id="fvp-playlist-play" title="'+t.playlist_play_all+'">'+t.playlist_play_all_button+"</span> </strong>"),playlist_menu=jQuery('<div class="fp-menu fv-fp-playlist-menu"> <a data-action="repeat_playlist"><svg viewBox="0 0 80.333 80" width="18px" height="18px" class="fvp-icon fvp-replay-list"><title>'+t.playlist_replay_all+'</title><use xlink:href="#fvp-replay-list"></use></svg> <span class="screen-reader-text">'+t.playlist_replay_all+'</span></a> <a data-action="shuffle_playlist"><svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-shuffle"><title>'+t.playlist_shuffle+'</title><use xlink:href="#fvp-shuffle"></use></svg> <span class="screen-reader-text">'+t.playlist_shuffle+'</span></a> <a data-action="repeat_track"><svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-replay-track"><title>'+t.playlist_replay_video+'</title><use xlink:href="#fvp-replay-track"></use></svg> <span class="screen-reader-text">'+t.playlist_replay_video+'</span></a> <a class="fp-selected" data-action="normal"><span id="fvp-playlist-play" title="'+t.playlist_play_all+'">'+t.playlist_play_all_button+"</span></a> </div>").insertAfter(root.find(".fp-controls"));api.conf.playlist_shuffle=api.conf.track_repeat=false;random_seed=randomize();var should_advance=api.conf.advance;playlist_button.insertAfter(root.find(".fp-controls .fp-volume")).on("click",function(e){e.preventDefault();e.stopPropagation();if(playlist_menu.css("right")!=="auto"){playlist_menu.css({right:"auto",left:playlist_button.position().left+"px"})}if(playlist_menu.hasClass("fp-active")){api.hideMenu(playlist_menu[0])}else{root.trigger("click");api.showMenu(playlist_menu[0])}});jQuery("a",playlist_menu).on("click",function(){jQuery(this).siblings("a").removeClass("fp-selected");jQuery(this).addClass("fp-selected");playlist_button.removeClass("mode-normal mode-repeat-track mode-repeat-playlist mode-shuffle-playlist");var action=jQuery(this).data("action");if(action=="repeat_playlist"){playlist_button.addClass("mode-repeat-playlist");api.conf.loop=true;api.conf.advance=true;api.video.loop=api.conf.track_repeat=false;api.conf.playlist_shuffle=false}else if(action=="shuffle_playlist"){playlist_button.addClass("mode-shuffle-playlist");api.conf.loop=true;api.conf.advance=true;api.conf.playlist_shuffle=true}else if(action=="repeat_track"){playlist_button.addClass("mode-repeat-track");api.conf.track_repeat=api.video.loop=true;api.conf.loop=api.conf.playlist_shuffle=false}else if(action=="normal"){playlist_button.addClass("mode-normal");api.conf.track_repeat=api.video.loop=false;api.conf.loop=api.conf.playlist_shuffle=false}if(api.conf.playlist_shuffle){api.next=function(){api.play(random_seed.pop());if(random_seed.length==0)random_seed=randomize()};api.prev=function(){api.play(random_seed.shift());if(random_seed.length==0)random_seed=randomize()}}else{api.next=original_next;api.prev=original_prev}});if(api.conf.loop){jQuery("a[data-action=repeat_playlist]",playlist_menu).trigger("click")}api.on("progress",function(){api.video.loop=api.conf.track_repeat});api.on("finish.pl",function(e,api){console.log("playlist_repeat",api.conf.loop,"advance",api.conf.advance,"video.loop",api.video.loop);if(api.conf.playlist_shuffle){api.play(random_seed.pop());if(random_seed.length==0)random_seed=randomize()}})}else if(root.find(".fv-fp-track-repeat").length==0&&api.conf.playlist.length==0){var button_track_repeat=jQuery('<strong class="fv-fp-track-repeat"><svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-replay-track"><use xlink:href="#fvp-replay-track"></use></svg></strong>');button_track_repeat.insertAfter(root.find(".fp-controls .fp-volume")).on("click",function(e){e.preventDefault();e.stopPropagation();jQuery(this).toggleClass("is-active fp-color-fill",api.video.loop);if(api.video.loop){api.video.loop=false}else{api.video.loop=true}});if(api.conf.loop){button_track_repeat.addClass("is-active fp-color-fill")}}}if(root.data("button-rewind")){if(root.find(".fv-fp-rewind").length==0){var button_rewind=jQuery('<span class="fv-fp-rewind"><svg viewBox="0 0 24 24" width="21px" height="21px" class="fvp-icon fvp-rewind"><use xlink:href="#fvp-rewind"></use></svg></span>');button_rewind.insertBefore(root.find(".fp-controls .fp-playbtn")).on("click",function(e){e.preventDefault();e.stopPropagation();api.seek(api.video.time-10)});button_rewind.toggle(!api.video.live)}if(root.find(".fv-fp-forward").length==0){var button_forward=jQuery('<span class="fv-fp-forward"><svg viewBox="0 0 24 24" width="21px" height="21px" class="fvp-icon fvp-forward"><use xlink:href="#fvp-forward"></use></svg></span>');button_forward.insertAfter(root.find(".fp-controls .fp-playbtn")).on("click",function(e){e.preventDefault();e.stopPropagation();api.seek(api.video.time+10)});button_forward.toggle(!api.video.live)}}}).bind("unload",function(){root.find(".fv-fp-no-picture").remove();root.find(".fv-fp-playlist").remove();root.find(".fv-fp-track-repeat").remove()});function array_shuffle(a){var j,x,i;for(i=a.length;i;i--){j=Math.floor(Math.random()*i);x=a[i-1];a[i-1]=a[j];a[j]=x}return a}function randomize(random_seed){random_seed=[];jQuery(api.conf.playlist).each(function(k,v){random_seed.push(k)});random_seed=array_shuffle(random_seed);console.log("FV Player Randomizer random seed:",random_seed);return random_seed}});flowplayer(function(api,root){var $root=jQuery(root),start_index=$root.data("playlist_start");if(typeof start_index=="undefined")return;function start_position_changer(){if($root.data("position_changed")!==1&&api.conf.playlist.length){start_index--;api.play(start_index);$root.data("position_changed",1)}}api.bind("unload",function(){start_index=$root.data("playlist_start");$root.removeData("position_changed");api.one("ready",start_position_changer)});api.one("ready",start_position_changer);jQuery(".fp-ui",root).on("click",function(){start_position_changer();$root.data("position_changed",1)})});document.addEventListener("custombox:overlay:close",function(e){console.log("FV Player: Custombox/Popup anything ligtbox closed");var $players=jQuery(this).find(".flowplayer");if($players.length==0)return;console.log("FV Player: Custombox/Popup anything ligtbox contains a player");$players.each(function(index,player){var api=jQuery(player).data("flowplayer");if(typeof api!="undefined"){if(api.playing){console.log("FV Player: Custombox/Popup anything ligtbox video pause");api.pause()}else if(api.loading){api.one("ready",function(){console.log("FV Player: Custombox/Popup anything ligtbox video unload");api.unload()})}}})});flowplayer(function(api,root){api.bind("finish",function(){var finished_at=api.video.time;if(api.video.loop){api.one("pause",function(){if(finished_at<=api.video.time){api.resume()}})}})});function fv_flowplayer_amazon_s3(hash,time){jQuery("#wpfp_"+hash).bind("error",function(e,api,error){var fv_fp_date=new Date;if(error.code==4&&fv_fp_date.getTime()>fv_fp_utime+parseInt(time)){jQuery(e.target).find(".fp-message").delay(500).queue(function(n){jQuery(this).html(fv_flowplayer_translations.video_expired);n()})}})}flowplayer(function(api,root){root=jQuery(root);root.find(".fp-logo").removeAttr("href");if(root.hasClass("no-controlbar")){var timelineApi=api.sliders.timeline;timelineApi.disable(true);api.bind("ready",function(){timelineApi.disable(true)})}jQuery(".fvfp_admin_error",root).remove();root.find(".fp-logo, .fp-header").on("click",function(e){if(e.target!==this)return;root.find(".fp-ui").trigger("click")});jQuery(".fvp-share-bar .sharing-facebook",root).append('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#fff"><title>Facebook</title><path d="M11.9 5.2l-2.6 0 0-1.6c0-0.7 0.3-0.7 0.7-0.7 0.3 0 1.6 0 1.6 0l0-2.9 -2.3 0c-2.6 0-3.3 2-3.3 3.3l0 2 -1.6 0 0 2.9 1.6 0c0 3.6 0 7.8 0 7.8l3.3 0c0 0 0-4.2 0-7.8l2.3 0 0.3-2.9Z"/></svg>');jQuery(".fvp-share-bar .sharing-twitter",root).append('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#fff"><title>Twitter</title><path d="M16 3.1c-0.6 0.3-1.2 0.4-1.9 0.5 0.7-0.4 1.2-1 1.4-1.8 -0.6 0.4-1.3 0.6-2.1 0.8 -0.6-0.6-1.4-1-2.4-1 -2 0.1-3.2 1.6-3.2 4 -2.7-0.1-5.1-1.4-6.7-3.4 -0.9 1.4 0.2 3.8 1 4.4 -0.5 0-1-0.1-1.5-0.4l0 0.1c0 1.6 1.1 2.9 2.6 3.2 -0.7 0.2-1.3 0.1-1.5 0.1 0.4 1.3 1.6 2.2 3 2.3 -1.6 1.7-4.6 1.4-4.8 1.3 1.4 0.9 3.2 1.4 5 1.4 6 0 9.3-5 9.3-9.3 0-0.1 0-0.3 0-0.4 0.6-0.4 1.2-1 1.6-1.7Z"/></svg>');jQuery(".fvp-share-bar .sharing-email",root).append('<svg xmlns="http://www.w3.org/2000/svg" height="16" viewBox="0 0 16 16" width="16" fill="#fff"><title>Email</title><path d="M8 10c0 0 0 0-1 0L0 6v7c0 1 0 1 1 1h14c1 0 1 0 1-1V6L9 10C9 10 8 10 8 10zM15 2H1C0 2 0 2 0 3v1l8 4 8-4V3C16 2 16 2 15 2z"/></svg>');jQuery(".fp-header",root).prepend(jQuery(".fvp-share-bar",root));if(api.conf.playlist.length){var show=true;var playlist=api.conf.playlist;if(playlist.length==2){if(typeof playlist[0].click!="undefined"&&typeof playlist[1].click=="undefined"){show=false}if(typeof playlist[0].click=="undefined"&&typeof playlist[1].click!="undefined"){show=false}}else if(playlist.length==3){if(typeof playlist[0].click!="undefined"&&typeof playlist[1].click=="undefined"&&typeof playlist[2].click!="undefined"){show=false}}if(show){var prev=jQuery('<a class="fp-icon fv-fp-prevbtn"></a>');var next=jQuery('<a class="fp-icon fv-fp-nextbtn"></a>');root.find(".fp-controls .fp-playbtn").before(prev).after(next);prev.on("click",function(){api.trigger("prev",[api]);api.prev()});next.on("click",function(){api.trigger("next",[api]);api.next()})}}if(typeof fv_player_editor_conf!="undefined"){root.on("click",".fvp-sharing > li",function(e){e.preventDefault();fv_player_notice(root,fv_player_editor_translations.link_notice,2e3);return false})}api.bind("pause resume finish unload ready",function(e,api){root.addClass("no-brand")});api.one("ready",function(){root.find(".fp-fullscreen").clone().appendTo(root.find(".fp-controls"))});api.on("ready",function(e,api,video){setTimeout(function(){jQuery(".fvp-share-bar",root).show();jQuery(".fv-player-buttons-wrap",root).appendTo(jQuery(".fv-player-buttons-wrap",root).parent().find(".fp-ui"))},100)});api.bind("finish",function(){var url=root.data("fv_redirect");if(url&&(typeof api.video.is_last=="undefined"||api.video.is_last)){location.href=url}});if(flowplayer.support.iOS&&flowplayer.support.iOS.version==11){api.bind("error",function(e,api,error){if(error.code==4)root.find(".fp-engine").hide()})}jQuery(document).on("contextmenu",".flowplayer",function(e){e.preventDefault()});api.one("ready",function(e,api,video){root.find(".fp-chromecast").insertAfter(root.find(".fp-header .fp-fullscreen"))});root.find(".fp-waiting").html('<div class="fp-preload"><b></b><b></b><b></b><b></b></div>');var id=root.attr("id"),alternative=!flowplayer.conf.native_fullscreen&&flowplayer.conf.mobile_alternative_fullscreen,events_enter="fakefullscreen",events_exit="fakefullscreen-exit";if(!flowplayer.support.fullscreen){events_enter+=" fullscreen";events_exit+=" fullscreen-exit"}api.bind(events_enter,function(e,api){jQuery("#wpadminbar, .nc_wrapper").hide();if(alternative||e.type=="fakefullscreen"){if(api.video.type=="video/youtube")return;root.before('<span data-fv-placeholder="'+id+'"></span>');root.appendTo("body")}});api.bind(events_exit,function(e,api,video){jQuery("#wpadminbar, .nc_wrapper").show();if(alternative||e.type=="fakefullscreen-exit"){jQuery("span[data-fv-placeholder="+id+"]").replaceWith(root)}})});(function(){var extension=function(flowplayer){flowplayer(function(api,root){if(!jQuery(root).data("speedb"))return;var support=flowplayer.support;if(!support.video||!support.inlineVideo)return;var common=flowplayer.common,bean=flowplayer.bean,ui=common.find(".fp-ui",root)[0],controlbar=common.find(".fp-controls",ui)[0],speeds=api.conf.speeds;bean.on(root,"click",".fp-speed",function(){var menu=common.find(".fp-speed-menu",root)[0];if(common.hasClass(menu,"fp-active"))api.hideMenu();else api.showMenu(menu)});bean.on(root,"click",".fp-speed-menu a",function(ev){var s=ev.target.getAttribute("data-speed");api.speed(s)});api.on("speed",function(ev,_a,rate){if(speeds.length>1){selectSpeed(rate)}}).on("ready",function(ev,api){removeMenu();if(flowplayer.support.android&&api.engine.engineName=="html5"&&api.video.type=="application/x-mpegurl")return;speeds=api.conf.speeds;if(speeds.length>1){createMenu()}});function removeMenu(){common.find(".fp-speed-menu",root).forEach(common.removeNode);common.find(".fp-speed",root).forEach(common.removeNode)}function round(val){return Math.round(val*100)/100}function createMenu(){controlbar.appendChild(common.createElement("strong",{className:"fp-speed"},api.currentSpeed+"x"));var menu=common.createElement("div",{className:"fp-menu fp-speed-menu",css:{width:"auto"}},"<strong>Speed</strong>");speeds.forEach(function(s){var a=common.createElement("a",{"data-speed":round(s)},round(s)+"x");menu.appendChild(a)});ui.appendChild(menu);selectSpeed(api.currentSpeed);jQuery(root).find(".fp-speed-menu strong").text(fv_flowplayer_translations.speed)}function selectSpeed(rate){common.find(".fp-speed",root)[0].innerHTML=rate+"x";common.find(".fp-speed-menu a",root).forEach(function(el){common.toggleClass(el,"fp-selected",el.getAttribute("data-speed")==rate);common.toggleClass(el,"fp-color",el.getAttribute("data-speed")==rate)})}})};if(typeof module==="object"&&module.exports)module.exports=extension;else if(typeof window.flowplayer==="function")extension(window.flowplayer)})();flowplayer(function(api,root){if(typeof fv_flowplayer_conf.disable_localstorage!="undefined"){return}api.on("speed",function(ev,_a,rate){try{window.localStorage.fv_player_speed=rate}catch(e){}});api.on("ready",function(){if(window.localStorage.fv_player_speed&&jQuery(root).find("strong.fp-speed").is(":visible")){api.speed(parseFloat(window.localStorage.fv_player_speed))}if(jQuery(root).data("volume")==0){api.mute(true,true)}})});flowplayer(function(api,root){root=jQuery(root);var last_tracked=-1;if(!api.conf.fv_stats||!api.conf.fv_stats.enabled&&(!root.data("fv_stats")||root.data("fv_stats")=="no"))return;api.on("ready finish",function(e,api){api.one("progress",function(e,api){if(root.data("fv_stats_data")){try{var player_post_data=root.data("fv_stats_data")}catch(e){return false}if(last_tracked==get_index())return;last_tracked=get_index();jQuery.post(api.conf.fv_stats.url,{blog_id:api.conf.fv_stats.blog_id,video_id:api.video.id?api.video.id:0,player_id:player_post_data.player_id,post_id:player_post_data.post_id,tag:"play"})}})}).on("finish",function(){last_tracked=-1});function get_index(){return api.video.index?api.video.index:0}});flowplayer(function(api,root){var $root=jQuery(root);var $playerDiv=$root.find(".fp-player");var sticky=$root.data("fvsticky");var globalSticky=false;var videoRatio=$root.data("ratio"),is_sticky=false;if(typeof videoRatio=="undefined"){videoRatio=.5625}if(flowplayer.conf.sticky_video==1&&typeof sticky=="undefined"){globalSticky=true}if(globalSticky||sticky){if(flowplayer.support.firstframe){var stickyPlace=flowplayer.conf.sticky_place;var stickyWidth=flowplayer.conf.sticky_width;if(stickyWidth==""){stickyWidth=380}var stickyHeight=stickyWidth*videoRatio;fv_player_sticky_video()}else{return}}function fv_player_sticky_video(){var change=false;var $window=jQuery(window),$flowplayerDiv=$root,top=$flowplayerDiv.offset().top,offset=Math.floor(top+$flowplayerDiv.outerHeight()/2);api.on("ready",function(){change=true});api.on("progress",function(){change=true});api.on("unload",function(){change=false;fv_player_sticky_class_remove();$root.removeClass("is-unSticky")});$window.on("resize",function(){if(!is_big_enough()){if(is_sticky){fv_player_sticky_class_remove()}return}top=$flowplayerDiv.offset().top;offset=Math.floor(top+$flowplayerDiv.outerHeight()/2)}).on("scroll",function(){if(!is_big_enough()){if(is_sticky){fv_player_sticky_class_remove()}return}top=$flowplayerDiv.offset().top;offset=Math.floor(top+$flowplayerDiv.outerHeight()/2);if($window.scrollTop()>offset&&change){if(jQuery("div.flowplayer.is-unSticky").length>0){console.log("unSticky",jQuery("div.flowplayer.is-unSticky").length);return false}else{fv_player_sticky_class_add()}}else{fv_player_sticky_class_remove();change=false}})}function fv_player_sticky_class_add(){if($playerDiv.hasClass("is-sticky-"+stickyPlace)){return}else{$playerDiv.addClass("is-sticky-"+stickyPlace);if($root.find("a.fp-sticky").length==0){$root.find("div.fp-header").prepend('<a class="fp-sticky fp-icon"></a>')}$playerDiv.css("width",stickyWidth);$playerDiv.css("height",stickyHeight);$playerDiv.css("max-height",stickyHeight);is_sticky=true;api.trigger("sticky",[api])}$playerDiv.parent(".flowplayer").addClass("is-stickable")}function fv_player_sticky_class_remove(){$playerDiv.removeClass("is-sticky-"+stickyPlace);$playerDiv.css("width","");$playerDiv.css("height","");$playerDiv.css("max-height","");$playerDiv.parent(".flowplayer").removeClass("is-stickable");if(is_sticky){is_sticky=false;api.trigger("sticky-exit",[api])}}function is_big_enough(){return jQuery(window).innerWidth()>=1020}});jQuery(function($){$(document).on("click","a.fp-sticky",function(){$("div.flowplayer.is-stickable").addClass("is-unSticky");var $playerDiv=$("div.flowplayer.is-stickable").find(".fp-player");$playerDiv.removeClass("is-sticky-right-bottom");$playerDiv.removeClass("is-sticky-left-bottom");$playerDiv.removeClass("is-sticky-right-top");$playerDiv.removeClass("is-sticky-left-top");$playerDiv.css("width","");$playerDiv.css("height","");$playerDiv.css("max-height","");if(is_sticky){is_sticky=false;api.trigger("sticky-exit",[api])}});$(document).on("click","div.flowplayer.is-unSticky",function(){$("div.flowplayer").removeClass("is-unSticky")})});flowplayer(function(api,root){root=jQuery(root);if(typeof fv_flowplayer_conf.disable_localstorage!="undefined"){return}var ls=window.localStorage;api.on("ready",function(e,api,video){if(root.find("strong.fp-cc").is(":visible")){if(ls.fv_player_subtitle&&api.video.subtitles.length){if(ls.fv_player_subtitle==="none"){api.disableSubtitles()}else{api.video.subtitles.forEach(function(item,index){if(item.srclang===ls.fv_player_subtitle){api.loadSubtitles(index)}})}}else{var defaultSubtitle=video.subtitles.filter(function(one){return one["fv_default"]})[0];if(defaultSubtitle){api.loadSubtitles(video.subtitles.indexOf(defaultSubtitle))}}}root.find(".fp-subtitle-menu").on("click",function(e){var subtitle_index=e.target.getAttribute("data-subtitle-index");if(typeof subtitle_index=="string"){try{ls.fv_player_subtitle=subtitle_index>-1?api.video.subtitles[subtitle_index].srclang:"none"}catch(e){}}})})});flowplayer(function(api,root){root=jQuery(root);var currentPoint,check=false;api.bind("cuepoint",function(e,api,cue){check=false;if(cue.subtitle){currentPoint=cue.index}});api.on("ready",function(e,api){root.find(".fp-subtitle-menu strong").text(fv_flowplayer_translations.closed_captions);root.find('.fp-subtitle-menu a[data-subtitle-index="-1"]').text(fv_flowplayer_translations.no_subtitles)});root.on("click",".fp-subtitle-menu a[data-subtitle-index]",function(e){if(jQuery(this).data("subtitle-index")>-1){check=true;api.on("progress",time_check)}});function time_check(e,api,time){if(check){(api.cuepoints||[]).forEach(function(cue,index){var entry=cue.subtitle;if(entry&&currentPoint!=index){if(time>=cue.time&&(!entry.endTime||time<=entry.endTime)){api.trigger("cuepoint",[api,cue])}}})}}});if(typeof flowplayer!=="undefined"&&typeof fv_flowplayer_conf!="undefined"&&fv_flowplayer_conf.video_hash_links){flowplayer(function(api,root){if(jQuery(root).find(".sharing-link").length>0){var abEnd,abStart,hash,sTime,abloop;function update_link(abStartNew,abEndNew){hash=fv_player_get_video_link_hash(api);sTime=","+fv_player_time_hms(api.video.time);if(abStartNew&&abEndNew){abStart=","+fv_player_time_hms_ms(abStartNew+api.get_custom_start());abEnd=","+fv_player_time_hms_ms(abEndNew+api.get_custom_start())}else{abEnd=abloop&&typeof api.get_ab_end()!="undefined"&&api.get_ab_end()?","+fv_player_time_hms_ms(api.get_ab_end()):"";abStart=abloop&&typeof api.get_ab_start()!="undefined"&&api.get_ab_start()?","+fv_player_time_hms_ms(api.get_ab_start()):""}jQuery(".sharing-link",root).attr("href",jQuery(".sharing-link",root).attr("href").replace(/#.*/,"")+"#"+hash+sTime+abStart+abEnd)}api.on("ready",function(e,api,video){if(!api.fv_noUiSlider)return;api.fv_noUiSlider.on("set",function(values){update_link(values[0],values[1])})});api.on("progress",function(e,api){if(!api.video.sources||!api.video.sources[0]){return}update_link()});api.on("abloop",function(e,api,active){abloop=active;if(!api.playing){update_link()}});jQuery(".sharing-link",root).on("click",function(e){fv_player_clipboard(jQuery(this).attr("href"),function(){e.preventDefault();fv_player_notice(root,fv_flowplayer_translations.link_copied,2e3)})})}});jQuery(document).on("click",'a[href*="fvp_"]',function(){var link=jQuery(this);setTimeout(function(){if(link.parents(".fvp-share-bar").length==0)fv_autoplay_exec()})})}flowplayer(function(api,root){root=jQuery(root);var bean=flowplayer.bean;var restore=flowplayer.conf.default_volume;root.on("mousedown touchstart",".fp-volumebtn",function(e){var volumebtn=jQuery(this);if(api.volumeLevel==0){volumebtn.one("click",function(){api.volume(restore);return false})}});root.on("mousedown touchstart mouseup touchend",".fp-volumebar",function(e){if(api.volumeLevel!=0){restore=api.volumeLevel}});api.on("volume",function(e,api){if(root.hasClass("is-mouseover")&&!api.muted){if(api.volumeLevel==0){bean.off(flowplayer.support.touch?root:document,"mousemove.sld touchmove.sld");api.mute(true)}}});var deal_with_muted_start=false;api.one("ready",function(e,api){if(root.hasClass("is-audio"))return;deal_with_muted_start=true});api.on("progress",function(e,api,time){if(deal_with_muted_start&&time>1){deal_with_muted_start=false;var video=jQuery("root").find("video");if(video.length&&!hasAudio(video[0])){return}if(api.muted||api.volumeLevel==0){if(localStorage.muted=="true"||localStorage.volume=="0"){return}var mute_notice=jQuery('<div class="fp-message fp-message-muted"><span class="fp-icon fp-volumebtn-notice"></span> '+fv_flowplayer_translations.click_to_unmute+"</div>");mute_notice.on("click touchstart",function(){api.mute(false);api.volume(1)});root.find(".fp-ui").append(mute_notice);root.addClass("has-fp-message-muted");setTimeout(remove_volume_notice,5e3)}}});api.on("mute volume",function(){if(!api.muted||api.volumeLevel>0){remove_volume_notice()}});function remove_volume_notice(){root.removeClass("has-fp-message-muted");root.find(".fp-message-muted").remove()}function hasAudio(video){return video.mozHasAudio||Boolean(video.webkitAudioDecodedByteCount)||Boolean(video.audioTracks&&video.audioTracks.length)}});if(typeof flowplayer!="undefined"){flowplayer(function(api,root){root=jQuery(root);if(navigator.userAgent.match(/iPhone.* OS [0-6]_/i)){api.one("progress",function(e){if(typeof api.video.subtitles!=="undefined"&&api.video.subtitles.length){fv_player_warning(root,fv_flowplayer_translations.warning_iphone_subs)}})}if(flowplayer.support.android&&flowplayer.support.android.version<5&&(flowplayer.support.android.samsung||flowplayer.support.browser.safari)){fv_player_warning(root,fv_flowplayer_translations.warning_unstable_android,"firefox")}if(/Android 4/.test(navigator.userAgent)&&!/Firefox/.test(navigator.userAgent)){api.on("ready",function(e,api,video){setTimeout(function(){if(video.src&&video.src.match(/fpdl.vimeocdn.com/)&&(video.time==0||video.time==1)){fv_player_warning(root,fv_flowplayer_translations.warning_unstable_android,"firefox");api.on("progress",function(e,api){root.prev().find(".fv-player-warning-firefox").remove()})}},1500)});api.on("error",function(e,api,error){if(error.MEDIA_ERR_NETWORK==2&&error.video.src.match(/fpdl.vimeocdn.com/)){fv_player_warning(root,fv_flowplayer_translations.warning_unstable_android,"firefox")}})}if(/Safari/.test(navigator.userAgent)&&/Version\/5/.test(navigator.userAgent)){api.on("error",function(e,api,error){if(error.video.src.match(/fpdl.vimeocdn.com/)){fv_player_warning(root,fv_flowplayer_translations.warning_old_safari)}})}var sup=flowplayer.support;if(sup.android&&(sup.android.samsung&&parseInt(sup.browser.version)<66||sup.browser.safari)){api.on("error",function(e,api,error){fv_player_warning(root,fv_flowplayer_translations.warning_samsungbrowser,"warning_samsungbrowser")})}});function fv_player_warning(root,warning,classname){var wrapper=jQuery(root).prev(".fv-player-warning-wrapper");if(wrapper.length==0){jQuery(root).before('<div class="fv-player-warning-wrapper">');wrapper=jQuery(root).prev(".fv-player-warning-wrapper")}if(wrapper.find(".fv-player-warning-"+classname).length==0){var latest=jQuery("<p style='display: none' "+(classname?" class='fv-player-warning-"+classname+"'":"")+">"+warning+"</p>");wrapper.append(latest);latest.slideDown()}}}
1
+ if(typeof fv_flowplayer_conf!="undefined"){try{if(typeof window.localStorage=="object"&&typeof window.localStorage.volume!="undefined"){delete fv_flowplayer_conf.volume}}catch(e){}flowplayer.conf=fv_flowplayer_conf;flowplayer.conf.fullscreen=false;flowplayer.conf.chromecast=false;flowplayer.conf.embed=false;flowplayer.conf.share=false;flowplayer.conf.analytics=false;if(typeof fv_flowplayer_conf.disable_localstorage!="undefined"){flowplayer.conf.storage={}}try{flowplayer.conf.key=atob(flowplayer.conf.key)}catch(e){}if(!flowplayer.support.android&&flowplayer.conf.dacast_hlsjs){function FVAbrController(hls){this.hls=hls;this.nextAutoLevel=3}FVAbrController.prototype.nextAutoLevel=function(nextLevel){this.nextAutoLevel=nextLevel};FVAbrController.prototype.destroy=function(){};flowplayer.conf.hlsjs={startLevel:-1,abrController:FVAbrController}}function parseIOSVersion(UA){var e=/iP(ad|hone)(; CPU)? OS (\d+_\d)/.exec(UA);if(e&&e.length>1){return parseFloat(e[e.length-1].replace("_","."),10)}return 0}if(flowplayer.support.iOS&&flowplayer.support.iOS.chrome&&flowplayer.support.iOS.version==0){flowplayer.support.iOS.version=parseIOSVersion(navigator.userAgent)}if(flowplayer.support.iOS&&parseInt(flowplayer.support.iOS.version)>=13||!flowplayer.support.iOS&&flowplayer.support.browser.safari&&parseInt(flowplayer.support.browser.version)>=8){flowplayer.conf.hlsjs.safari=true}flowplayer.support.fvmobile=!!(!flowplayer.support.firstframe||flowplayer.support.iOS||flowplayer.support.android);var fls=flowplayer.support;if(flowplayer.conf.mobile_native_fullscreen&&"ontouchstart"in window&&fls.fvmobile){flowplayer.conf.native_fullscreen=true}if("ontouchstart"in window){if(fls.android&&fls.android.version<4.4&&!(fls.browser.chrome&&fls.browser.version>54)){flowplayer.conf.native_fullscreen=true}if(fls.iOS&&(fv_player_in_iframe()||fls.iOS.version<7)){flowplayer.conf.native_fullscreen=true}}}if(typeof fv_flowplayer_translations!="undefined"){flowplayer.defaults.errors=fv_flowplayer_translations}var fv_player_did_autoplay=false;function fv_player_videos_parse(args,root){try{var videos=JSON.parse(args)}catch(e){return false}var regex=new RegExp("[\\?&]fv_flowplayer_mobile=([^&#]*)");var results=regex.exec(location.search);if((results!=null&&results[1]=="yes"||(jQuery(window).width()<=480||jQuery(window).height()<=480))&&(results==null||results[1]!="no")){var fv_fp_mobile=false;jQuery(videos.sources).each(function(k,v){if(v.mobile){videos.sources[k]=videos.sources[0];videos.sources[0]=v;fv_fp_mobile=true}if(fv_fp_mobile){jQuery(root).after('<p class="fv-flowplayer-mobile-switch">'+fv_flowplayer_translations.mobile_browser_detected_1+' <a href="'+document.URL+'?fv_flowplayer_mobile=no">'+fv_flowplayer_translations.mobile_browser_detected_2+"</a>.</p>")}})}root.trigger("fv_player_videos_parse",videos);return videos}function fv_player_in_iframe(){try{return window.self!==window.top}catch(e){return true}}jQuery(document).ready(function(){var loading_count=0;var loading=setInterval(function(){loading_count++;if(loading_count<1e3&&(window.fv_video_intelligence_conf&&!window.FV_Player_IMA||window.fv_vast_conf&&!window.FV_Player_IMA||window.fv_player_pro&&!window.FV_Flowplayer_Pro&&document.getElementById("fv_player_pro")!=fv_player_pro||window.fv_player_user_playlists&&!fv_player_user_playlists.is_loaded||window.FV_Player_JS_Loader_scripts_total&&window.FV_Player_JS_Loader_scripts_loaded<FV_Player_JS_Loader_scripts_total)){return}clearInterval(loading);fv_player_preload()},10)});function fv_escape_attr(text){var map={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return text.replace(/[&<>"']/g,function(m){return map[m]})}function fv_player_preload(){if(flowplayer.support.touch){jQuery(".fp-playlist-external.fv-playlist-design-2017").addClass("visible-captions")}flowplayer(function(api,root){if(localStorage.flowplayerTestStorage){delete localStorage.flowplayerTestStorage}root=jQuery(root);var fp_player=root.find(".fp-player");var splash_click=false;if(root.hasClass("fixed-controls")){root.find(".fp-controls").on("click",function(e){if(!api.loading&&!api.ready){e.preventDefault();e.stopPropagation();api.load()}})}if(!flowplayer.support.volume&&!flowplayer.support.autoplay){root.find(".fp-volume").hide()}if(root.data("volume")==0&&root.hasClass("no-controlbar")){root.find(".fp-volume").remove()}var playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]");if((!api.conf.playlist||api.conf.playlist.length==0)&&playlist.length&&playlist.find("a[data-item]").length>0){var items=[];playlist.find("a[data-item]").each(function(){if(parsed=fv_player_videos_parse(jQuery(this).attr("data-item"),root)){items.push(parsed)}else{jQuery(this).remove()}});api.conf.playlist=items;api.conf.clip=items[0]}else if(!api.conf.clip){api.conf.clip=fv_player_videos_parse(jQuery(root).attr("data-item"),root)}jQuery("a",playlist).on("click",function(e){e.preventDefault();splash_click=true;var $this=jQuery(this),playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]"),index=jQuery("a",playlist).index(this);$prev=$this.prev("a"),item=$this.data("item");if(location.href.match(/wp-admin/)&&$this.parents(".fv-player-editor-preview").length>0){fv_flowplayer_conf.current_video_to_edit=index;$this.parents(".fv-player-custom-video").find(".edit-video .fv-player-editor-button").trigger("click");return false}if($prev.length&&$this.is(":visible")&&!$prev.is(":visible")){$prev.trigger("click");return false}if(jQuery("#"+$this.parent().attr("rel")).hasClass("dynamic-playlist"))return;var playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]");fv_player_playlist_active(playlist,this);if(api){if(api.error){api.pause();api.error=api.loading=false;root.removeClass("is-error");root.find(".fp-message.fp-shown").remove()}if(!api.video||api.video.index==index)return;api.play(index)}var new_splash=item.splash;if(!new_splash){new_splash=$this.find("img").attr("src")}player_splash(root,fp_player,item,new_splash);var rect=root[0].getBoundingClientRect();if(rect.bottom-100<0){jQuery("html, body").animate({scrollTop:jQuery(root).offset().top-100},300)}});var playlist_external=jQuery("[rel="+root.attr("id")+"]");var playlist_progress=false;var splash_img=root.find(".fp-splash");var splash_text=root.find(".fv-fp-splash-text");function player_splash(root,fp_player,item,new_splash){var splash_img=root.find("img.fp-splash");if(new_splash){if(splash_img.length==0){splash_img=jQuery('<img class="fp-splash" />');fp_player.prepend(splash_img)}splash_img.attr("alt",item.fv_title?fv_escape_attr(item.fv_title):"video");splash_img.attr("src",new_splash)}else if(splash_img.length){splash_img.remove()}}api.bind("load",function(e,api,video){if(!api.conf.playlist.length){return}if(video.type.match(/^audio/)&&!splash_click){var anchor=playlist_external.find("a").eq(video.index);var item=anchor.data("item");var new_splash=item.splash;if(!new_splash){new_splash=anchor.find("img").attr("src")}player_splash(root,fp_player,item,new_splash)}splash_click=false});api.bind("ready",function(e,api,video){setTimeout(function(){if(video.index>-1){if(playlist_external.length>0){var playlist_item=jQuery("a",playlist_external).eq(video.index);fv_player_playlist_active(playlist_external,playlist_item);playlist_progress=playlist_item.find(".fvp-progress")}}},100);splash_img=root.find(".fp-splash");if(!video.is_audio_stream&&!video.type.match(/^audio/)){if(window.fv_player_pro&&window.fv_player_pro.autoplay_scroll||root.data("fvautoplay")){api.one("progress",function(){splash_img.remove();splash_text.remove()})}else{splash_img.remove();splash_text.remove()}}});api.bind("unload",function(){jQuery(".fp-playlist-external .now-playing").remove();jQuery(".fp-playlist-external a").removeClass("is-active");var iframe=fp_player.find("iframe.fp-engine");if(iframe.length){iframe.after(splash_text);iframe.after(splash_img)}else{fp_player.prepend(splash_text);fp_player.prepend(splash_img)}playlist_progress=false});api.bind("progress",function(e,api,time){if(playlist_progress.length){api.playlist_thumbnail_progress(playlist_progress,api.video,time)}});api.bind("error-subtitles",function(){console.log("error-subtitles");fv_player_notice(root,fv_flowplayer_translations[8],2e3)});var playlist=jQuery(root).parent().find("div.fp-playlist-vertical[rel="+jQuery(root).attr("id")+"]");if(playlist.length){function check_size_and_all(args){var property=playlist.hasClass("fp-playlist-only-captions")?"height":"max-height";if(playlist.parents(".fp-playlist-text-wrapper").hasClass("is-fv-narrow")){property="max-height"}playlist.css(property,vertical_playlist_height());if(property=="max-height")playlist.css("height","auto")}check_size_and_all();jQuery(window).on("resize tabsactivate",function(){setTimeout(check_size_and_all,0)})}function vertical_playlist_height(args){var height=root.height();if(height==0)height=root.css("max-height");return height}api.show_status=function(type){var status="";["loading","ready","playing","paused","seeking"].every(function(v,k){if(api[v])status+=" "+v;return true});console.log("FV Player Status ("+type+")",status)};if(!window.fv_player_loaded){window.fv_player_loaded=true;setTimeout(function(){jQuery(document).trigger("fv_player_loaded");var event=new CustomEvent("fv_player_loaded",[]);document.dispatchEvent(event)},100)}setTimeout(function(){root.trigger("fv_player_loaded")},10)});if(window.self!=window.top&&!location.href.match(/fv_player_preview/)){embed_size();jQuery(window.self).resize(embed_size)}function embed_size(){jQuery(".flowplayer.fp-is-embed").each(function(){var root=jQuery(this);if(!root.hasClass("has-chapters")&&!root.hasClass("has-transcript")&&jQuery(".fp-playlist-external[rel="+root.attr("id")+"]").length==0){root.height(jQuery(window).height())}})}if(typeof fv_flowplayer_playlists!="undefined"){for(var i in fv_flowplayer_playlists){if(!fv_flowplayer_playlists.hasOwnProperty(i))continue;jQuery("#"+i).flowplayer({playlist:fv_flowplayer_playlists[i]})}}fv_player_load();fv_autoplay_exec();jQuery(document).ajaxComplete(function(){fv_player_load()});jQuery(window).on("hashchange",fv_autoplay_exec)}function fv_player_load(forced_el){if(forced_el&&forced_el.lenght>1){console.log("FV Player: Can't use fv_player_load with more than a single forced element!")}var load_players=forced_el,forced_api=false;if(!load_players)load_players=jQuery(".flowplayer");load_players.each(function(i,el){var root=jQuery(el);var api=root.data("flowplayer");if(api){if(forced_el)forced_api=api;return}if(forced_el){root.find(".fp-preload, .fvfp_admin_error").remove();if(root.attr("data-item-lazy")){root.attr("data-item",root.attr("data-item-lazy"));root.removeAttr("item-lazy")}else if(playlist=jQuery("[rel="+root.attr("id")+"]")){playlist.find("a[data-item-lazy]").each(function(k,v){v=jQuery(v);v.attr("data-item",v.attr("data-item-lazy"));v.removeAttr("data-item-lazy")})}}var conf=false;if(root.attr("data-item")){conf={clip:fv_player_videos_parse(root.attr("data-item"),root)}}else if(playlist=jQuery("[rel="+root.attr("id")+"]")){if(playlist.find("a[data-item]").length==0)return;var items=[];playlist.find("a[data-item]").each(function(){if(parsed=fv_player_videos_parse(jQuery(this).attr("data-item"),root)){items.push(parsed)}else{jQuery(this).remove()}});conf={playlist:items}}if(conf){conf=flowplayer.extend(conf,root.data());forced_api=flowplayer(root[0],conf);root.data("flowplayer",forced_api)}});jQuery(".fv-playlist-slider-wrapper").each(function(i,el){var items=jQuery(this).find("a");jQuery(this).find(".fp-playlist-external").css("width",items.outerWidth()*items.length)});if(typeof jQuery().tabs!="undefined"){jQuery("body").removeClass("fv_flowplayer_tabs_hide");jQuery(".fv_flowplayer_tabs_content").tabs()}if(forced_el&&forced_api){return forced_api}}function fv_player_playlist_active(playlist,item){if(playlist){jQuery("a",playlist).removeClass("is-active");jQuery(".now-playing").remove()}$playlist=jQuery(playlist);$item=jQuery(item);var scroll_parent=false;$item.addClass("is-active");var is_design_2014=$playlist.hasClass("fv-playlist-design-2014");if((is_design_2014&&$item.find("h4").length==0||!is_design_2014)&&$item.find(".now-playing").length==0)$item.prepend('<strong class="now-playing"><span>'+fv_flowplayer_translations.playlist_current+"</span></strong>");if(!$playlist.parent().find(".flowplayer").length){scroll_parent=true}if(($playlist.hasClass("fp-playlist-vertical")||$playlist.hasClass("fp-playlist-horizontal")&&$playlist.hasClass("is-audio"))&&!fullyVisibleY($item.get(0))){var $el=scroll_parent?$playlist.parent():$playlist;$el.animate({scrollTop:$el.scrollTop()+($item.position().top-$el.position().top)},750)}else if($playlist.hasClass("fp-playlist-horizontal")&&!fullyVisibleX($item.get(0))){var $el=scroll_parent?$playlist.parent():$playlist;$el.animate({scrollLeft:$el.scrollLeft()+($item.position().left-$el.position().left)},750)}function fullyVisibleY(el){var rect=el.getBoundingClientRect(),top=rect.top,height=rect.height,bottom=top+height,el=el.parentNode;do{rect=el.getBoundingClientRect();if(bottom<=rect.bottom===false)return false;if(top<=rect.top)return false;el=el.parentNode}while(el!=document.body);return bottom<=document.documentElement.clientHeight}function fullyVisibleX(el){var rect=el.getBoundingClientRect(),left=rect.left,width=rect.width,right=left+width,el=el.parentNode;do{rect=el.getBoundingClientRect();if(right<=rect.right===false)return false;if(left<=rect.left)return false;el=el.parentNode}while(el!=document.body);return right<=document.documentElement.clientWidth}}var fv_fp_date=new Date;var fv_fp_utime=fv_fp_date.getTime();function fv_parse_sharelink(src){src=src.replace("https?://[^./].","");var prefix="fvp_";if(src.match(/(youtube.com)/)){return prefix+src.match(/(?:v=)([A-Za-z0-9_-]*)/)[1]}else if(src.match(/(vimeo.com)|(youtu.be)/)){return prefix+src.match(/(?:\/)([^/]*$)/)[1]}else{var match=src.match(/(?:\/)([^/]*$)/);if(match){return prefix+match[1].match(/^[^.]*/)[0]}}return prefix+src}function fv_player_get_video_link_hash(api){var hash=fv_parse_sharelink(typeof api.video.sources_original!="undefined"&&typeof api.video.sources_original[0]!="undefined"?api.video.sources_original[0].src:api.video.sources[0].src);if(typeof api.video.id!="undefined"){hash=fv_parse_sharelink(api.video.id.toString())}return hash}function fv_player_time_hms(seconds){if(isNaN(seconds)){return NaN}var sec_num=parseInt(seconds,10);var hours=Math.floor(sec_num/3600);var minutes=Math.floor(sec_num/60)%60;var seconds=sec_num%60;if(hours){hours+="h"}else{hours=""}if(hours&&minutes<10){minutes="0"+minutes+"m"}else if(minutes){minutes+="m"}else{minutes=""}if((hours||minutes)&&seconds<10){seconds="0"+seconds}seconds+="s";var timeString=hours+minutes+seconds;return timeString}function fv_player_time_hms_ms(seconds){if(isNaN(seconds)){return NaN}seconds=parseFloat(seconds).toFixed(3);var miliseconds=(seconds+"").split(".");if(typeof miliseconds[1]!="undefined"&&miliseconds[1]>0){miliseconds=miliseconds[1]+"ms"}else{miliseconds=""}var timeString=fv_player_time_hms(seconds)+miliseconds;return timeString}function fv_player_time_seconds(time,duration){if(!time)return-1;var seconds=0;var match=time.match(/(\d+[a-z]{1,2})/g);match.forEach(function(item){if(item.endsWith("h")){seconds+=3600*parseInt(item)}else if(item.endsWith("m")){seconds+=60*parseInt(item)}else if(item.endsWith("s")&&!item.endsWith("ms")){seconds+=parseInt(item)}else if(item.endsWith("ms")){if(parseInt(item)){seconds+=parseInt(item)/1e3}}});return duration?Math.min(seconds,duration):seconds}function fv_autoplay_init(root,index,time,abStart,abEnd){if(fv_autoplay_exec_in_progress)return;fv_autoplay_exec_in_progress=true;var api=root.data("flowplayer");if(!api)return;var fTime=fv_player_time_seconds(time);abEnd=fv_player_time_seconds(abEnd);abStart=fv_player_time_seconds(abStart);if(root.parent().hasClass("ui-tabs-panel")){var tabId=root.parent().attr("id");jQuery("[aria-controls="+tabId+"] a").trigger("click")}if(!root.find(".fp-player").attr("class").match(/\bis-sticky/)){var offset=jQuery(root).offset().top-(jQuery(window).height()-jQuery(root).height())/2;window.scrollTo(0,offset);api.one("ready",function(){window.scrollTo(0,offset)})}if(root.hasClass("lightboxed")){setTimeout(function(){jQuery("[href=\\#"+root.attr("id")+"]").trigger("click")},0)}if(index){if(fv_player_video_link_autoplay_can(api,parseInt(index))){if(api.ready){fv_player_video_link_seek(api,fTime)}else{api.play(parseInt(index));api.one("ready",function(){fv_player_video_link_seek(api,fTime,abEnd,abStart)})}}else if(flowplayer.support.inlineVideo){api.one(api.playing?"progress":"ready",function(e,api){api.play(parseInt(index));api.one("ready",function(){fv_player_video_link_seek(api,fTime,abEnd,abStart)})});root.find(".fp-splash").attr("src",jQuery("[rel="+root.attr("id")+"] div").eq(index).find("img").attr("src"));if(!fv_player_in_iframe()){fv_player_notice(root,fv_flowplayer_translations[11],"progress")}}}else{if(api.ready){fv_player_video_link_seek(api,fTime)}else{if(fv_player_video_link_autoplay_can(api)){api.load()}else if(!fv_player_in_iframe()){fv_player_notice(root,fv_flowplayer_translations[11],"progress")}api.one("ready",function(){fv_player_video_link_seek(api,fTime,abEnd,abStart)})}}}function fv_player_video_link_seek(api,fTime,abEnd,abStart){fv_autoplay_exec_in_progress=false;var do_seek=setInterval(function(){if(api.loading)return;if(fTime>0||api.video.time>0){if(!!api.custom_seek){api.custom_seek(fTime)}else{api.seek(fTime)}}if(abEnd&&abStart)api.trigger("link-ab",[api,abStart,abEnd]);clearInterval(do_seek)},10)}var fv_autoplay_exec_in_progress=false;function fv_autoplay_exec(){var autoplay=true;if(typeof flowplayer!=="undefined"&&typeof fv_flowplayer_conf!="undefined"&&fv_flowplayer_conf.video_hash_links&&window.location.hash.substring(1).length){var aHash=window.location.hash.match(/\?t=/)?window.location.hash.substring(1).split("?t="):window.location.hash.substring(1).split(",");var hash=aHash[0];var time=aHash[1]===undefined?false:aHash[1];var abStart=aHash[2]===undefined?false:aHash[2];var abEnd=aHash[3]===undefined?false:aHash[3];jQuery(".flowplayer").each(function(){var root=jQuery(this);if(root.hasClass("lightbox-starter")){root=jQuery(root.attr("href"))}var api=root.data("flowplayer");if(!api)return;var playlist=typeof api.conf.playlist!=="undefined"&&api.conf.playlist.length>1?api.conf.playlist:[api.conf.clip];for(var item in playlist){if(!playlist.hasOwnProperty(item))continue;var id=typeof playlist[item].id!=="undefined"?fv_parse_sharelink(playlist[item].id.toString()):false;if(hash===id&&autoplay){console.log("fv_autoplay_exec for "+id,item);fv_autoplay_init(root,parseInt(item),time,abStart,abEnd);autoplay=false;return false}}for(var item in playlist){if(!playlist.hasOwnProperty(item))continue;var src=fv_parse_sharelink(playlist[item].sources[0].src);if(hash===src&&autoplay){console.log("fv_autoplay_exec for "+src,item);fv_autoplay_init(root,parseInt(item),time,abStart,abEnd);autoplay=false;return false}}})}if(autoplay&&flowplayer.support.firstframe){jQuery(".flowplayer[data-fvautoplay]").each(function(){var root=jQuery(this),api=root.data("flowplayer"),autoplay=root.attr("data-fvautoplay");if(!fv_player_did_autoplay&&autoplay){if(autoplay==-1){return}if((flowplayer.support.android||flowplayer.support.iOS)&&api&&api.conf.clip.sources[0].type=="video/youtube"){console.log("FV Player: Autoplay for YouTube not supported on Android and iOS");return}else{fv_player_did_autoplay=true;if(api.conf.playlist.length&&!isNaN(parseFloat(autoplay))&&isFinite(autoplay)){api.play(parseInt(autoplay))}else{api.load()}var play_icon=root.find(".fp-play").addClass("invisible"),control_bar=root.find(".fp-controls").addClass("invisible");api.one("progress",function(){play_icon.removeClass("invisible");control_bar.removeClass("invisible")});if(autoplay=="muted"){api.mute(true,true)}}}})}}function fv_player_video_link_autoplay_can(api,item){var video=item?api.conf.playlist[item]:api.conf.clip;if(video.sources[0].type=="video/youtube"&&(flowplayer.support.iOS||flowplayer.support.android)||fv_player_in_iframe())return false;return flowplayer.support.firstframe}function fv_player_notice(root,message,timeout){var notices=jQuery(".fvfp-notices",root);if(!notices.length){notices=jQuery('<div class="fvfp-notices">');jQuery(".fp-player",root).append(notices)}var notice=jQuery('<div class="fvfp-notice-content">'+message+"</div></div>");notices.append(notice);if(typeof timeout=="string"){var player=jQuery(root).data("flowplayer");player.on(timeout,function(){notice.fadeOut(100,function(){jQuery(this).remove()})})}if(timeout>0){setTimeout(function(){notice.fadeOut(2e3,function(){jQuery(this).remove()})},timeout)}return notice}var fv_player_clipboard=function(text,successCallback,errorCallback){if(navigator.clipboard&&typeof navigator.clipboard.writeText=="function"){navigator.clipboard.writeText(text).then(function(){successCallback()},function(){errorCallback()});return}try{if(fv_player_doCopy(text)){successCallback()}else{errorCallback()}}catch(e){if(typeof errorCallback!="undefined")errorCallback(e)}};function fv_player_doCopy(text){var textarea=document.createElement("textarea");textarea.value=text;textarea.style.opacity=0;textarea.style.position="absolute";textarea.setAttribute("readonly",true);document.body.appendChild(textarea);var selected=document.getSelection().rangeCount>0?document.getSelection().getRangeAt(0):false;if(navigator.userAgent.match(/ipad|ipod|iphone/i)){var editable=textarea.contentEditable;textarea.contentEditable=true;var range=document.createRange();range.selectNodeContents(textarea);var sel=window.getSelection();sel.removeAllRanges();sel.addRange(range);textarea.setSelectionRange(0,999999);textarea.contentEditable=editable}else{textarea.select()}try{var result=document.execCommand("copy");if(selected){document.getSelection().removeAllRanges();document.getSelection().addRange(selected)}document.body.removeChild(textarea);return result}catch(err){throw new Error("Unsuccessfull")}}flowplayer(function(api,root){root=jQuery(root);if(typeof api.conf.disable_localstorage!="undefined"){return}var hlsjs;flowplayer.engine("hlsjs-lite").plugin(function(params){hlsjs=params.hls;hlsjs.on(Hls.Events.ERROR,function(event,data){if(data.type=="mediaError"&&data.details=="fragParsingError"&&data.fatal==true){hlsjs.destroy();api.trigger("error",[api,{code:3}]);setTimeout(function(){root.removeClass("is-seeking");root.addClass("is-paused")},0)}});if(flowplayer.support.browser.safari){hlsjs.on(Hls.Events.KEY_LOADED,function(event){if(event=="hlsKeyLoaded"){setTimeout(function(){if(api.loading){console.log("FV Player: Safari stuck loading HLS, resuming playback...");api.resume()}},0)}})}var pick_quality=flowplayer.conf.hd_streaming&&!flowplayer.support.fvmobile?720:false;if(jQuery(params.root).data("hd_streaming")==false)pick_quality=false;if(localStorage.FVPlayerHLSQuality)pick_quality=localStorage.FVPlayerHLSQuality;if(pick_quality){hlsjs.on(Hls.Events.MANIFEST_PARSED,function(_,data){var found=false;jQuery.each(data.levels,function(k,v){if(v.height==pick_quality)found=k});if(!localStorage.FVPlayerHLSQuality&&!found){jQuery.each(data.levels,function(k,v){if(v.height>found)found=k})}if(found){console.log("FV Player: Picked "+data.levels[found].height+"p quality");hlsjs.startLevel=found;hlsjs.currentLevel=found}})}});root=jQuery(root);var search=document.location.search;if(localStorage.FVPlayerDashQuality){if(!api.conf.dash)api.conf.dash={};api.conf.dash.initialVideoQuality="restore"}root.on("click",".fp-qsel-menu a",function(){if(api.engine.engineName=="hlsjs-lite"){var quality=jQuery(this).data("quality");if(quality==-1){localStorage.removeItem("FVPlayerHLSQuality")}else{var level=hlsjs.levels[quality];localStorage.FVPlayerHLSQuality=level.height}}});if(localStorage.FVPlayerHLSQuality){api.conf.hlsjs.startLevel=parseInt(localStorage.FVPlayerHLSQuality);api.conf.hlsjs.testBandwidth=false;api.conf.hlsjs.autoLevelEnabled=false}else if(flowplayer.conf.hd_streaming&&!flowplayer.support.fvmobile){api.conf.hlsjs.startLevel=3;api.conf.hlsjs.testBandwidth=false;api.conf.hlsjs.autoLevelEnabled=false}api.bind("quality",function(e,api,quality){if(api.engine.engineName=="dash"){if(quality==-1){localStorage.removeItem("FVPlayerDashQuality")}else if(bitrates[quality]){localStorage.FVPlayerDashQuality=bitrates[quality].height}}});var bitrates=[];var last_quality=-1;api.bind("ready",function(e,api){root.find(".fp-qsel-menu strong").text(fv_flowplayer_translations.quality);if(api.engine.engineName=="dash"){bitrates=api.engine.dash.getBitrateInfoListFor("video");if(localStorage.FVPlayerDashQuality&&api.conf.dash.initialVideoQuality){api.quality(api.conf.dash.initialVideoQuality)}quality_sort()}else if(api.engine.engineName=="hlsjs-lite"){root.addClass("is-loading");api.loading=true;api.one("progress",function(){if(api.loading){root.removeClass("is-loading");api.loading=false}});if(api.video.qualities&&api.video.qualities.length>2){var qswitch=-1;if(localStorage.FVPlayerHLSQuality){jQuery(api.video.qualities).each(function(k,v){if(v.value==localStorage.FVPlayerHLSQuality){qswitch=localStorage.FVPlayerHLSQuality;return false}})}else if(flowplayer.conf.hd_streaming&&!flowplayer.support.fvmobile){jQuery(api.video.qualities).each(function(k,v){var height=parseInt(v.label);if(height>0&&qswitch==-1&&height>=720&&height<=720){qswitch=v.value}})}qswitch=parseInt(qswitch);if(qswitch>-1){root.one("progress",function(){setTimeout(function(){api.quality(qswitch)})})}quality_sort()}}else if(api.video.sources_fvqs&&api.video.sources_fvqs.length>0&&api.video.src.match(/vimeo.*?\.mp4/)){setTimeout(quality_sort,0)}root.find("a[data-quality]").removeClass("is-current")});if(search.match(/dash_debug/)||search.match(/hls_debug/))var debug_log=jQuery('<div class="fv-debug" style="background: gray; color: white; top: 10%; position: absolute; z-index: 1000">').appendTo(root.find(".fp-player"));api.bind("ready progress",quality_process);api.bind("quality",function(){setTimeout(quality_process,0)});function quality_process(){if(api.engine.engineName=="dash"){var stream_info=bitrates[api.engine.dash.getQualityFor("video")];if(stream_info.qualityIndex!=last_quality){last_quality=stream_info.qualityIndex;quality_label(stream_info.qualityIndex,bitrates)}if(search.match(/dash_debug/))quality_debug(stream_info.width,stream_info.height,stream_info.bitrate)}else if(api.engine.engineName=="hlsjs-lite"){if(hlsjs.currentLevel!=last_quality){last_quality=hlsjs.currentLevel;quality_label(hlsjs.currentLevel,hlsjs.levels)}if(search.match(/hls_debug/)){var level=hlsjs.levels[hlsjs.currentLevel];if(level){quality_debug(level.width,level.height,level.bitrate)}}}}function quality_label(index,qualities){if(!qualities[index])return;var height=qualities[index].height,hd_limit=541,lowest=1e5;jQuery(qualities).each(function(k,v){if(v.height>=720&&v.height<1400)hd_limit=720;if(v.height<lowest)lowest=v.height;if(localStorage.FVPlayerHLSQuality==v.height){root.find("a[data-quality]").removeClass("fp-selected fp-color");root.find("a[data-quality="+k+"]").addClass("fp-selected fp-color")}});root.find("a[data-quality]").removeClass("is-current");root.find("a[data-quality="+index+"]").addClass("is-current");var label="SD";if(height>=360&&lowest<height)label="SD";if(height>=hd_limit)label="HD";if(height>=1400)label="4K";root.find(".fp-qsel").html(label)}function quality_debug(w,h,br){debug_log.html("Using "+w+"x"+h+" at "+Math.round(br/1024)+" kbps")}function quality_sort(){var menu=root.find(".fp-qsel-menu");menu.children().each(function(i,a){menu.prepend(a)});menu.children().each(function(i,a){if(/^NaNp/.test(jQuery(a).html())){var bitrate=jQuery(a).html().match(/\((.*?)\)/);if(bitrate&&typeof bitrate[1]!=="undefined"){jQuery(a).html(bitrate[1])}}else{jQuery(a).html(jQuery(a).html().replace(/\(.*?\)/,""))}});menu.prepend(menu.find("a[data-quality=-1]"));menu.prepend(menu.find("strong"))}});flowplayer(function(api,root){root=jQuery(root);var player_id=root.attr("id"),ad=false;if(root.data("end_popup_preview")){jQuery(document).ready(function(){api.trigger("finish",[api])})}function ad_height_check(){var count=0;var ad_height_check=setInterval(function(){var height=ad&&ad.find(".adsbygoogle").height();count++;if(count>20*10||height>0)clearInterval(ad_height_check);if(height>root.height()){ad.addClass("tall-ad")}},50)}function show_ad(){var ad_data=root.attr("data-ad");if(typeof ad_data!="undefined"&&ad_data.length){try{ad_data=JSON.parse(ad_data)}catch(e){return false}if(!ad&&!root.hasClass("is-cva")&&root.width()>=parseInt(ad_data.width)){var html=ad_data.html;html=html.replace("%random%",Math.random());ad=jQuery('<div id="'+player_id+'_ad" class="wpfp_custom_ad">'+html+"</div>");root.find(".fp-player").append(ad);ad_height_check();setTimeout(function(){if(root.find(".wpfp_custom_ad video").length){api.pause()}},500)}}}function show_popup(event){var popup_data=root.attr("data-popup");if(typeof popup_data!="undefined"&&popup_data.length){try{popup_data=JSON.parse(popup_data)}catch(e){return false}if((event=="finish"||popup_data.pause||popup_data.html.match(/fv-player-ppv-purchase-btn-wrapper/))&&root.find(".wpfp_custom_popup").length==0){root.addClass("is-popup-showing");root.find(".fp-player").append('<div id="'+player_id+'_custom_popup" class="wpfp_custom_popup">'+popup_data.html+"</div>")}}}api.bind("ready",function(e,api){if(ad.length==1){ad.remove();ad=false}if(!root.data("ad_show_after")){show_ad()}}).bind("progress",function(e,api,current){if(current>root.data("ad_show_after")){show_ad()}}).bind("finish",function(e,api){if(typeof api.video.index=="undefined"||api.video.index+1==api.conf.playlist.length){show_popup(e.type)}}).bind("pause",function(e,api){show_popup(e.type)}).bind("resume unload seek",function(e,api){if(root.hasClass("is-popup-showing")){root.find(".wpfp_custom_popup").remove();root.removeClass("is-popup-showing")}})});jQuery(document).on("click",".fv_fp_close",function(){var ad=jQuery(this).parents(".wpfp_custom_ad_content"),video=ad.find("video");ad.fadeOut();if(video.length)video[0].pause();return false});jQuery(document).on("focus",".fv_player_popup input[type=text], .fv_player_popup input[type=email], .fv_player_popup textarea",function(){var api=jQuery(this).parents(".flowplayer").data("flowplayer");if(api)api.disable(true)});jQuery(document).on("blur",".fv_player_popup input[type=text], .fv_player_popup input[type=email], .fv_player_popup textarea",function(){var api=jQuery(this).parents(".flowplayer").data("flowplayer");if(api)api.disable(false)});flowplayer(function(api,root){api.on("ready",function(e,api,video){api.one("progress",function(){jQuery(root).find(".fp-airplay").toggle(api.engine.engineName=="html5")})})});flowplayer(function(api,root){var root=jQuery(root),bean=flowplayer.bean,time=0,last=0,timer,event_name;if(typeof ga=="undefined"&&api.conf.fvanalytics&&typeof _gat=="undefined"&&typeof gtag=="undefined"){if(is_ga_4(api)){jQuery.getScript({url:"https://www.googletagmanager.com/gtag/js?id="+api.conf.fvanalytics,cache:true},function(){window.dataLayer=window.dataLayer||[];window.gtag=function(){window.dataLayer.push(arguments)};window.gtag("js",new Date);window.gtag("config",api.conf.fvanalytics)})}else{jQuery.getScript({url:"https://www.google-analytics.com/analytics.js",cache:true},function(){ga("create",api.conf.fvanalytics,"auto")})}}if(!window._paq&&api.conf.matomo_domain&&api.conf.matomo_site_id){var u="//"+api.conf.matomo_domain+"/";var _paq=window._paq=window._paq||[];_paq.push(["setTrackerUrl",u+"matomo.php"]);_paq.push(["setSiteId",api.conf.matomo_site_id]);var d=document,g=d.createElement("script"),s=d.getElementsByTagName("script")[0];g.type="text/javascript";g.async=true;g.src=u+"matomo.js";s.parentNode.insertBefore(g,s)}api.bind("progress",function(e,api,current){fv_track(e,api,current)}).bind("finish ready ",function(e,api){for(var j in fv_ga_events){if(!fv_ga_events.hasOwnProperty(j))continue;root.removeData("fv_track_"+fv_ga_events[j])}}).bind("error",function(e,api,error){setTimeout(function(){if(!api.error)return;var video=typeof api.video!="undefined"&&typeof api.video.src!="undefined"?api.video:false;if(!video&&typeof api.conf.clip!="undefined"&&typeof api.conf.clip.sources!="undefined"&&typeof api.conf.clip.sources[0]!="undefined"&&typeof api.conf.clip.sources[0].src!="undefined")video=api.conf.clip.sources[0];var name=fv_player_track_name(root,video);if(name&&!name.match(/\/\/vimeo.com\/\d/)){if(is_ga_4(api)){}else{fv_player_track(api,false,"Video "+(root.hasClass("is-cva")?"Ad ":"")+"error",error.message,name)}}},100)});api.bind("load unload",fv_track_seconds_played).bind("progress",function(e,api){if(!api.seeking){time+=last?+new Date-last:0;last=+new Date}if(!timer){timer=setTimeout(function(){timer=null;if(!is_ga_4(api)){fv_player_track(api,false,"Flowplayer heartbeat",api.engine.engineName+"/"+api.video.type,"Heartbeat",0)}},10*60*1e3)}}).bind("pause",function(){last=0});api.bind("shutdown",function(){bean.off(window,"unload",fv_track_seconds_played)});bean.on(window,"unload",fv_track_seconds_played);var fv_ga_events=is_ga_4(api)?["Play","25 Percent Played","50 Percent Played","75 Percent Played","100 Percent Played"]:["start","first quartile","second quartile","third quartile","complete"];function fv_track_seconds_played(e,api_not_needed,video){video=video||api.video;if(e.type==="load"){event_name=fv_player_track_name(root,video)}if(time){fv_player_track(api,false,"Video / Seconds played",api.engine.engineName+"/"+api.video.type,event_name,Math.round(time/1e3));time=0;if(timer){clearTimeout(timer);timer=null}}}function fv_track(e,api,data){var video=api.video,dur=video.duration,i=0;var name=fv_player_track_name(root,video);if(dur){if(data>19*dur/20)i=4;else if(data>3*dur/4)i=3;else if(data>dur/2)i=2;else if(data>dur/4)i=1}if(api.live)i=0;if(root.data("fv_track_"+fv_ga_events[i]))return;for(var j in fv_ga_events){if(!fv_ga_events.hasOwnProperty(j))continue;if(j==i)break;if(!root.data("fv_track_"+fv_ga_events[j]))return}root.trigger("fv_track_"+fv_ga_events[i].replace(/ /,"_"),[api,name]);root.data("fv_track_"+fv_ga_events[i],true);fv_player_track(api,false,"Video "+(root.hasClass("is-cva")?"Ad ":"")+fv_ga_events[i],api.engine.engineName+"/"+video.type,name)}api.get_time_played=function(){return time/1e3}});function is_ga_4(api){if(typeof api.conf.fvanalytics!="undefined"&&api.conf.fvanalytics&&api.conf.fvanalytics.startsWith("G-"))return true;return false}function fv_player_track(api,ga_id,event,engineType,name,value){if(typeof api!="object"){value=name;name=engineType;engineType=event;event=ga_id;ga_id=api;api=false}if(!ga_id)ga_id=flowplayer.conf.fvanalytics;if(typeof engineType=="undefined")engineType="Unknown engine";if(/fv_player_track_debug/.test(window.location.href))console.log("FV Player Track: "+event+" - "+engineType+" '"+name+"'",value);if(typeof gtag!="undefined"){if(is_ga_4(api)){gtag("event",event,{video_current_time:api.video.time,video_provider:engineType,video_duration:api.video.duration,value:value?value:1})}else{gtag("event",event,{event_category:engineType,event_label:name,value:value?value:1})}}else if(ga_id&&typeof ga!="undefined"){ga("create",ga_id,"auto",name,{allowLinker:true});ga("require","linker");if(value){ga("send","event",event,engineType,name,value)}else{ga("send","event",event,engineType,name)}}else if(ga_id&&typeof _gat!="undefined"){var tracker=_gat._getTracker(ga_id);if(typeof tracker._setAllowLinker=="undefined"){return}tracker._setAllowLinker(true);if(value){tracker._trackEvent(event,engineType,name,value)}else{tracker._trackEvent(event,engineType,name)}}if(flowplayer.conf.matomo_domain&&flowplayer.conf.matomo_site_id&&typeof _paq!="undefined"){if(value){_paq.push(["trackEvent",event,engineType,name,value])}else{_paq.push(["trackEvent",event,engineType,name])}}}function fv_player_track_name(root,video){var name=root.attr("title");if(!name&&typeof video.fv_title!="undefined")name=video.fv_title;if(!name&&typeof video.title!="undefined")name=video.title;if(!name&&typeof video.src!="undefined"){name=video.src.split("/").slice(-1)[0].replace(/\.(\w{3,4})(\?.*)?$/i,"");if(video.type.match(/mpegurl/))name=video.src.split("/").slice(-2)[0].replace(/\.(\w{3,4})(\?.*)?$/i,"")+"/"+name}return name}flowplayer(function(api,root){root=jQuery(root);var player=root.find(".fp-player"),had_no_volume=root.hasClass("no-volume"),had_fp_mute=root.hasClass("fp-mute"),had_fp_full=root.hasClass("fp-full"),buttons_count=0;function check_size(){var width=player.width()||root.width(),video_index=api.video.index?api.video.index:0;if(width>900){jQuery(".fp-subtitle",root).addClass("is-wide")}else{jQuery(".fp-subtitle",root).removeClass("is-wide")}root.toggleClass("is-tiny",width<400);root.toggleClass("is-small",width<600&&width>=400);var too_narrow=width<480+buttons_count*35;if(typeof api.fv_timeline_chapters_data!="undefined"&&typeof api.fv_timeline_chapters_data[video_index]!="undefined"){too_narrow=true}if(!had_fp_full){root.toggleClass("fp-full",root.hasClass("has-abloop")||too_narrow)}var size="";if(width<400)size="is-tiny";else if(width<600&&width>=400)size="is-small";root.trigger("fv-player-size",[size]);var el=player;if(root.parent().hasClass("fp-playlist-vertical-wrapper")||root.parent().hasClass("fp-playlist-text-wrapper"))el=root.parent();if(el.width()<=560){el.addClass("is-fv-narrow")}else{el.removeClass("is-fv-narrow")}if(width<=320){root.addClass("no-volume fp-mute")}else{if(!had_no_volume)root.removeClass("no-volume");if(!had_fp_mute)root.removeClass("fp-mute")}}check_size();jQuery(window).on("resize",check_size);if("fonts"in document){api.one("load",function(){document.fonts.load("1em flowplayer")})}api.on("ready fullscreen fullscreen-exit sticky sticky-exit",function(e){setTimeout(function(){buttons_count=root.find(".fp-controls > strong:visible").length+root.find(".fp-controls > .fp-icon:visible").length;check_size()},0)});api.on("unload pause finish error",function(){if(typeof checker!=="undefined")clearInterval(checker)})});jQuery(window).on("resize tabsactivate",function(){jQuery(".fp-playlist-external").each(function(){var playlist=jQuery(this);if(playlist.parent().width()>=900)playlist.addClass("is-wide");else playlist.removeClass("is-wide")})}).trigger("resize");flowplayer(function(api,root){api.bind("ready",function(){if(/Chrome/.test(navigator.userAgent)&&parseFloat(/Chrome\/(\d\d)/.exec(navigator.userAgent)[1],10)>54){if(api.video.subtitles){jQuery(root).addClass("chrome55fix-subtitles")}else{jQuery(root).addClass("chrome55fix")}}});root=jQuery(root);var image_src=root.css("background-image");if(image_src){image_src=image_src.replace(/url\((['"])?(.*?)\1\)/gi,"$2").split(",");if(!image_src||!image_src[0].match(/^(https?:)?\/\//))return;var image=new Image;image.src=image_src[0];var image_ratio=image.height/image.width;var player_ratio=root.height()/root.width();var ratio_diff=Math.abs(player_ratio-image_ratio);if(ratio_diff<.05){root.css("background-size","cover")}}});(function($){$(window).on("resize",function(){var iframe=$("iframe[id][src][height][width]");iframe.each(function(){if($(this).attr("id").match(/(fv_vimeo_)|(fv_ytplayer_)/)&&$(this).width()<=$(this).attr("width"))$(this).height($(this).width()*$(this).attr("height")/$(this).attr("width"))});var wistia=jQuery(".wistia_embed");wistia.each(function(){$(this).height($(this).width()*$(this).data("ratio"))})}).trigger("resize")})(jQuery);jQuery(document).on("tabsactivate",".fv_flowplayer_tabs_content",function(event,ui){var oldPlayer=jQuery(ui.oldPanel).find(".flowplayer").data("flowplayer");if(typeof oldPlayer!="undefined"){oldPlayer.pause()}var objPlayer=jQuery(".flowplayer",ui.newPanel);var api=objPlayer.data("flowplayer");api.load()});flowplayer(function(api,root){root=jQuery(root);var bean=flowplayer.bean;if(root.hasClass("is-audio")){bean.off(root[0],"mouseenter");bean.off(root[0],"mouseleave");root.removeClass("is-mouseout");root.addClass("fixed-controls").addClass("is-mouseover");api.on("error",function(e,api,error){jQuery(".fp-message",root).html(jQuery(".fp-message",root).html().replace(/video/,"audio"))});root.on("click",function(e){if(!api.ready){e.preventDefault();e.stopPropagation();api.load()}})}});flowplayer(function(api,root){if(!api.conf.fv_chromecast)return;if(!window["__onGCastApiAvailable"]){jQuery.getScript({url:"https://www.gstatic.com/cv/js/sender/v1/cast_sender.js",cache:true});window["__onGCastApiAvailable"]=function(loaded){if(!loaded)return;initialize()}}var conf=api.conf.chromecast||{},session,timer,trigger,bean=flowplayer.bean,common=flowplayer.common,waiting_for_seek=false;function initialize(){var applicationId,sessionRequest,apiConfig;applicationId=conf.applicationId||chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;sessionRequest=new chrome.cast.SessionRequest(applicationId);apiConfig=new chrome.cast.ApiConfig(sessionRequest,sessionListener,receiverListener);chrome.cast.initialize(apiConfig,onInitSuccess,onError)}function sessionListener(){}function receiverListener(ev){console.log("FV Player: Chromecast listener",ev);if(ev!==chrome.cast.ReceiverAvailability.AVAILABLE)return;flowplayer.conf.chromecast_available=true}function onInitSuccess(){}function onError(){console.log("chromecast onError")}function createUIElements(){var btnContainer=common.find(".fp-header",root)[0];if(!btnContainer)return;common.find(".fp-chromecast",btnContainer).forEach(common.removeNode);common.find(".fp-chromecast-engine",root).forEach(common.removeNode);trigger=common.createElement("a",{class:"fp-chromecast fp-icon",title:"Play on Cast device"});btnContainer.appendChild(trigger);var chromeCastEngine=common.createElement("div",{class:"fp-chromecast-engine"}),chromeCastStatus=common.createElement("p",{class:"fp-chromecast-engine-status"}),chromeCastIcon=common.createElement("p",{class:"fp-chromecast-engine-icon"});chromeCastEngine.appendChild(chromeCastIcon);chromeCastEngine.appendChild(chromeCastStatus);var engine=common.find(".fp-engine",root)[0];if(!engine)common.prepend(common.find(".fp-player",root)[0]||root,chromeCastEngine);else engine.parentNode.insertBefore(chromeCastEngine,engine)}function destroy(){clearInterval(timer);timer=null;api.release();common.toggleClass(root,"is-chromecast",false);common.toggleClass(trigger,"fp-active",false)}function get_media(){var media=false;var sources=api.video.sources_fvqs||api.video.sources;for(var i in sources){var type=sources[i].type;if(type=="video/mp4"||type=="video/fv-mp4"||type=="application/dash+xml"){media=sources[i];break}}if(!media){for(var i in sources){if(sources[i].type=="application/x-mpegurl"){media=sources[i];break}}}if(api.video.fvhkey&&!api.conf.hls_cast)return false;if(media){var top_quality=false,mp4_qualities=["fullhd","hd","md","sd"];for(var quality in mp4_qualities){var re=new RegExp("-"+mp4_qualities[quality]);for(var i in api.video.sources_fvqs){var source=api.video.sources_fvqs[i];if(source.src.match(re)&&source.type=="video/mp4"){top_quality=source;break}}if(top_quality){media=top_quality;break}}}return media}function load_media(){var media=get_media();if(!media){return false}var cast_subtitles=[];if(api.video.subtitles){api.video.subtitles.forEach(function(v,k){if(v.src.match(/\.srt/)){console.log("FV Player: Chromecast doesn't support SRT subtitles")}var subtitles=new chrome.cast.media.Track(k,chrome.cast.media.TrackType.TEXT);subtitles.trackContentId=v.src;subtitles.trackContentType="text/vtt";subtitles.subtype=chrome.cast.media.TextTrackType.SUBTITLES;subtitles.name=v.label;subtitles.language=v.srclang+"-"+k,subtitles.customData=null;cast_subtitles.push(subtitles)})}var mediaInfo=new chrome.cast.media.MediaInfo(media.src,media.type);mediaInfo.tracks=cast_subtitles;var request=new chrome.cast.media.LoadRequest(mediaInfo);if(!api.live){request.currentTime=api.video.time}clearInterval(timer);timer=false;session.loadMedia(request,onMediaDiscovered,function onMediaError(e){console.log("onMediaError",e)})}function onMediaDiscovered(chromecast){switch_tracks(chromecast);chromecast.addUpdateListener(function(alive){if(!session)return;timer=timer||setInterval(function(){api.trigger("progress",[api,chromecast.getEstimatedTime()]);chromecast.activeTrackIds.forEach(function(track_id){jQuery.each(chromecast.media.tracks,function(k,v){if(v.trackId==track_id&&v.type=="AUDIO"){var found=hilight_audio_track("data-audio",v.language);if(!found){hilight_audio_track("data-lang",v.language)}return false}})})},500);if(alive){common.toggleClass(root,"is-chromecast",true);common.toggleClass(trigger,"fp-active",true);api.hijack({pause:function(){console.log("hijacked pause!");chromecast.pause()},resume:function(){if(api.finished){clearInterval(timer);timer=null;api.release();load_media();return}chromecast.play()},seek:function(time){var req=new chrome.cast.media.SeekRequest;req.currentTime=time;chromecast.seek(req)}})}var playerState=chromecast.playerState;if(api.paused&&playerState===chrome.cast.media.PlayerState.PLAYING)api.trigger("resume",[api]);if(api.playing&&playerState===chrome.cast.media.PlayerState.PAUSED)api.trigger("pause",[api]);if(api.seeking&&playerState===chrome.cast.media.PlayerState.BUFFERING){waiting_for_seek=true}if(api.seeking&&playerState===chrome.cast.media.PlayerState.PLAYING&&waiting_for_seek){waiting_for_seek=false;api.trigger("seek",[api])}if(playerState==chrome.cast.media.PlayerState.IDLE&&chromecast.idleReason==chrome.cast.media.IdleReason.FINISHED){api.trigger("finish",[api])}common.toggleClass(root,"is-loading",playerState===chrome.cast.media.PlayerState.BUFFERING)})}api.bind("ready",function(e,api,video){if(session){if(get_media()){api.one("progress",function(e,api){api.release();api.pause();api.mute(false,true);load_media()});api.mute(true,true)}else{session.stop();session=null;destroy();jQuery(trigger).hide()}return}if(!flowplayer.conf.chromecast_available)return;if(get_media()){createUIElements();jQuery(trigger).show()}else{FV_Flowplayer_Pro.log("FV Player: Can't find media source suitable for Chromecast!");jQuery(trigger).hide()}});bean.on(root,"click",".fp-chromecast",function(ev){ev.preventDefault();if(session){api.trigger("pause",[api]);if(session.media[0].media){var seek=session.media[0].getEstimatedTime();setTimeout(function(){api.seek(seek)},0)}session.stop();session=null;destroy();return}if(api.playing)api.pause();chrome.cast.requestSession(function(s){jQuery(root).addClass("is-loading");session=s;var receiverName=session.receiver.friendlyName;common.html(common.find(".fp-chromecast-engine-status",root)[0],"Playing on device "+receiverName);load_media()},function(err){console.error("requestSession error",err)})});bean.on(root,"click",".fv-fp-hls-menu [data-audio], .fp-subtitle-menu [data-subtitle-index]",function(){if(session&&session.media[0].media){switch_tracks(session.media[0]);return false}});jQuery(window).on("unload",function(){if(session){session.stop()}});function hilight_audio_track(attr,chromecast_language){var audio_tracks_menu=jQuery(root).find(".fv-fp-hls-menu a"),found=false;audio_tracks_menu.each(function(k,el){if(jQuery(el).attr(attr)===chromecast_language){jQuery(el).addClass("fp-selected");found=true}else{jQuery(el).removeClass("fp-selected")}});return found}function switch_tracks(chromecast){console.log(chromecast.media.tracks);var audio=jQuery(root).find(".fv-fp-hls-menu [data-audio].fp-selected").data("audio"),audio_lang=jQuery(root).find(".fv-fp-hls-menu [data-audio].fp-selected").data("lang"),subtitle_index=jQuery(root).find(".fp-subtitle-menu [data-subtitle-index].fp-selected").data("subtitle-index"),subtitles=subtitle_index>-1?api.video.subtitles[subtitle_index].srclang:false;var audio_found=false,subtitles_found=false,tracks_selected=[];jQuery.each(chromecast.media.tracks,function(k,v){if(v.language==audio&&v.type=="AUDIO"){audio_found=v}if(v.language==subtitles+"-"+subtitle_index&&v.type=="TEXT"){subtitles_found=v}});if(!audio_found){jQuery.each(chromecast.media.tracks,function(k,v){if(v.language==audio_lang&&v.type=="AUDIO"){audio_found=v;return false}})}var debug_log="";if(audio_found){tracks_selected.push(audio_found.trackId);debug_log+=audio_found.language+" audio"}if(subtitles_found){tracks_selected.push(subtitles_found.trackId);if(debug_log)debug_log+=" ";debug_log+=subtitles_found.language+" subtitles"}if(tracks_selected){var request=new chrome.cast.media.EditTracksInfoRequest(tracks_selected);chromecast.editTracksInfo(request,function(){console.log("FV Player: Chromecast "+debug_log+" loaded")},function(){console.log("FV Player: Chromecast "+debug_log+" failed")})}}});jQuery(document).on("mfpClose",function(){if(typeof jQuery(".flowplayer").data("flowplayer")!="undefined")jQuery(".flowplayer").data("flowplayer").unload()});jQuery(document).on("click",".vc_tta-tab a",function(){var api=jQuery(".flowplayer.is-playing").data("flowplayer");if(api)api.pause()});flowplayer(function(api,root){root=jQuery(root);api.bind("ready",function(){setTimeout(function(){var video=jQuery("video",root);if(video.length>0){video.prop("autoplay",false)}},100);root.find("video.fp-engine").addClass("intrinsic-ignore")})});jQuery(".flowplayer").on("ready",function(e,api){if(/BB10/.test(navigator.userAgent)){api.fullscreen()}});var fv_flowplayer_safety_resize_arr=Array();function fv_flowplayer_safety_resize(){var fv_flowplayer_safety_resize_init=false;jQuery(".flowplayer").each(function(){if(!jQuery(this).is(":visible")||jQuery(this).hasClass("lightboxed")||jQuery(this).hasClass("lightbox-starter")||jQuery(this).hasClass("is-audio"))return;if(jQuery(this).width()<30||jQuery(this).height()<20){fv_flowplayer_safety_resize_init=true;var el=jQuery(this);while(jQuery(el).width()<30||jQuery(el).width()==jQuery(this).width()){if(jQuery(el).parent().length==0)break;el=jQuery(el).parent();if(el.hasClass("ld-video")){if(el[0].style.height==""){el.css("height","auto")}if(parseInt(el.css("padding-bottom"))>0){el.css("padding-bottom","0")}}}jQuery(this).width(jQuery(el).width());jQuery(this).height(parseInt(jQuery(this).width()*jQuery(this).attr("data-ratio")));fv_flowplayer_safety_resize_arr[jQuery(this).attr("id")]=el}});if(fv_flowplayer_safety_resize_init){jQuery(window).resize(function(){jQuery(".flowplayer").each(function(){if(jQuery(this).hasClass("lightboxed")||jQuery(this).hasClass("lightbox-starter"))return;if(fv_flowplayer_safety_resize_arr[jQuery(this).attr("id")]){jQuery(this).width(fv_flowplayer_safety_resize_arr[jQuery(this).attr("id")].width());jQuery(this).height(parseInt(jQuery(this).width()*jQuery(this).attr("data-ratio")))}})})}}if(typeof flowplayer.conf.safety_resize!="undefined"&&flowplayer.conf.safety_resize){jQuery(document).ready(function(){setTimeout(function(){fv_flowplayer_safety_resize()},10)})}var isIE11=!!navigator.userAgent.match(/Trident.*rv[ :]*11\./);if(isIE11){jQuery(document).ready(function(){jQuery(".fp-waiting").hide()});flowplayer(function(api,root){api.bind("load",function(e){jQuery(e.currentTarget).find(".fp-waiting").show()}).bind("beforeseek",function(e){jQuery(e.currentTarget).find(".fp-waiting").show()}).bind("progress",function(e){jQuery(e.currentTarget).find(".fp-waiting").hide()}).bind("seek",function(e){jQuery(e.currentTarget).find(".fp-waiting").hide()}).bind("fullscreen",function(e){jQuery("#wpadminbar").hide()}).bind("fullscreen-exit",function(e){jQuery("#wpadminbar").show()})})}if(flowplayer.support.browser&&flowplayer.support.browser.msie&&parseInt(flowplayer.support.browser.version,10)<9){jQuery(".flowplayer").each(function(){jQuery(this).css("width",jQuery(this).css("max-width"));jQuery(this).css("height",jQuery(this).css("max-height"))})}if(location.href.match(/elementor-preview=/)){console.log("FV Player: Elementor editor is active");setInterval(fv_player_load,1e3)}else if(location.href.match(/brizy-edit-iframe/)){console.log("FV Player: Brizy editor is active");setInterval(fv_player_load,1e3)}if(window.DELEGATE_NAMES){flowplayer(function(api,root){fv_player_notice(root,fv_flowplayer_translations.chrome_extension_disable_html5_autoplay)})}flowplayer(function(api,root){flowplayer.bean.off(root,"contextmenu")});if(location.href.match(/elementor-preview=/)){console.log("FV Player: Elementor editor is active");setInterval(fv_player_load,1e3)}flowplayer(function(player,root){root=jQuery(root);if(typeof root.data("fv-embed")=="undefined"||!root.data("fv-embed")||root.data("fv-embed")=="false")return;player.embedCode=function(){var video=player.video;var width=root.width();var height=root.height();height+=2;if(root.hasClass("has-chapters")||root.hasClass("has-transcript")){height+=300}if(jQuery(".fp-playlist-external[rel="+root.attr("id")+"]").length>0){height+=150+20}var link=root.data("fv-embed")+"#"+fv_player_get_video_link_hash(player);return'<iframe src="'+link+'" allowfullscreen width="'+width+'" height="'+height+'" frameborder="0" style="max-width:100%"></iframe>'}});jQuery(document).on("click",".flowplayer .embed-code-toggle",function(){var root=jQuery(this).closest(".flowplayer");if(typeof fv_player_editor_conf!="undefined"){fv_player_notice(root,fv_player_editor_translations.embed_notice,2e3);return false}var button=jQuery(this);var player=button.parents(".flowplayer");var api=player.data("flowplayer");if(typeof api.embedCode=="function"){player.find(".embed-code textarea").val(api.embedCode())}fv_player_clipboard(player.find(".embed-code textarea").val(),function(){fv_player_notice(player,fv_flowplayer_translations.embed_copied,2e3)},function(){button.parents(".fvp-share-bar").find(".embed-code").toggle();button.parents(".fvp-share-bar").toggleClass("visible")});return false});flowplayer(function(player,root){if(jQuery(root).data("fullscreen")==false){return}player.one("ready",function(e,api,video){if(jQuery(root).find(".fp-fullscreen").length==0){jQuery(root).find(".fp-header").append('<a class="fp-fullscreen fp-icon"></a>')}});var FS_ENTER="fullscreen",FS_EXIT="fullscreen-exit",FS_SUPPORT=flowplayer.support.fullscreen,win=window,scrollX,scrollY,bean=flowplayer.bean;player.fullscreen=function(flag){if(player.disabled)return;var video=common.find("video.fp-engine",root)[0];if(flowplayer.conf.native_fullscreen&&video&&flowplayer.support.iOS){player.trigger(FS_ENTER,[player]);bean.on(document,"webkitfullscreenchange.nativefullscreen",function(){if(document.webkitFullscreenElement!==video)return;bean.off(document,".nativefullscreen");bean.on(document,"webkitfullscreenchange.nativefullscreen",function(){if(document.webkitFullscreenElement)return;bean.off(document,".nativefullscreen");player.trigger(FS_EXIT,[player])})});video.webkitEnterFullScreen();bean.one(video,"webkitendfullscreen",function(){bean.off(document,"fullscreenchange.nativefullscreen");player.trigger(FS_EXIT,[player]);common.prop(video,"controls",true);common.prop(video,"controls",false)});return}var wrapper=jQuery(root).find(".fp-player")[0];if(flag===undefined)flag=!player.isFullscreen;if(flag){scrollY=win.scrollY;scrollX=win.scrollX}if(FS_SUPPORT){if(flag){["requestFullScreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen"].forEach(function(fName){if(typeof wrapper[fName]==="function"){wrapper[fName]({navigationUI:"hide"});if(fName==="webkitRequestFullScreen"&&!document.webkitFullscreenElement){wrapper[fName]()}}})}else{["exitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"].forEach(function(fName){if(typeof document[fName]==="function"){document[fName]()}})}}else{player.trigger(flag?FS_ENTER:FS_EXIT,[player])}return player};var lastClick,common=flowplayer.common;player.on("mousedown.fs",function(){if(+new Date-lastClick<150&&player.ready)player.fullscreen();lastClick=+new Date});player.on(FS_ENTER,function(){common.addClass(root,"is-fullscreen");common.toggleClass(root,"fp-minimal-fullscreen",common.hasClass(root,"fp-minimal"));common.removeClass(root,"fp-minimal");if(!FS_SUPPORT)common.css(root,"position","fixed");player.isFullscreen=true}).on(FS_EXIT,function(){var oldOpacity;common.toggleClass(root,"fp-minimal",common.hasClass(root,"fp-minimal-fullscreen"));common.removeClass(root,"fp-minimal-fullscreen");if(!FS_SUPPORT&&player.engine==="html5"){oldOpacity=root.css("opacity")||"";common.css(root,"opacity",0)}if(!FS_SUPPORT)common.css(root,"position","");common.removeClass(root,"is-fullscreen");if(!FS_SUPPORT&&player.engine==="html5")setTimeout(function(){root.css("opacity",oldOpacity)});player.isFullscreen=false;if(player.engine.engineName!="fvyoutube"){win.scrollTo(scrollX,scrollY)}}).on("unload",function(){if(player.isFullscreen)player.fullscreen()});player.on("shutdown",function(){FULL_PLAYER=null;common.removeNode(wrapper)})});flowplayer(function(api,root){root=jQuery(root);if(flowplayer.conf.wpadmin||jQuery(root).hasClass("is-audio"))return;var playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]"),playlist_with_fullscreen=playlist.hasClass("fp-playlist-season")||playlist.hasClass("fp-playlist-polaroid");fsforce=root.data("fsforce")==true;if(root.data("fullscreen")==false){return}if(flowplayer.conf.mobile_force_fullscreen&&flowplayer.support.fvmobile||!flowplayer.support.fullscreen&&fsforce||playlist_with_fullscreen){if(!flowplayer.support.fullscreen){api.bind("ready",function(){if(api.video.vr)return;api.fullscreen(true)})}root.on("click",function(){if(!api.ready||api.paused)api.fullscreen(true)});jQuery("[rel="+root.attr("id")+"] a").on("click",function(e){if(!api.isFullscreen){api.fullscreen();api.resume()}});api.on("resume",function(){if(api.video.vr)return;if(!api.isFullscreen)api.fullscreen()});api.on("finish",function(){if(api.conf.playlist.length==0||api.conf.playlist.length-1==api.video.index)api.fullscreen(false)}).on("fullscreen",function(a,api){root.addClass("forced-fullscreen")}).on("fullscreen-exit",function(a,api){api.pause();root.removeClass("forced-fullscreen")})}else if(fsforce){var position,unload=root.find(".fp-unload"),is_closing=false;api.isFakeFullscreen=false;unload.show();root.on("click",function(e){if(!api.ready&&e.target!=unload[0])api.fakeFullscreen(true)});unload.on("click",function(e){if(api.ready){api.fullscreen(false)}else if(api.loading){is_closing=true;api.one("resume",function(e){is_closing=false;api.pause()})}api.fakeFullscreen(false);return false});jQuery("[rel="+root.attr("id")+"] a").on("click",function(e){if(!api.isFakeFullscreen){api.fakeFullscreen();api.resume()}});api.on("resume",function(){if(!is_closing&&!api.isFakeFullscreen)api.fakeFullscreen()}).on("finish",function(){if(api.conf.playlist.length==0||api.conf.playlist.length-1==api.video.index)api.fakeFullscreen(false)}).on("fullscreen",function(a,api){root.removeClass("fake-fullscreen")}).on("fullscreen-exit",function(a,api){if(api.isFakeFullscreen)api.fakeFullscreen(true,true)}).on("unload",function(a,api){});api.fakeFullscreen=function(flag,force){if(!force&&(api.isFakeFullscreen==flag||api.disabled))return;if(position===undefined)position=root.css("position");if(flag===undefined)flag=!api.isFakeFullscreen;api.isFakeFullscreen=flag;api.trigger(flag?"fakefullscreen":"fakefullscreen-exit",[api]);root.toggleClass("is-fullscreen fake-fullscreen forced-fullscreen",flag);if(flag){root.css("position","fixed")}else{root.css("position",position)}}}if(flowplayer.support.android&&flowplayer.conf.mobile_landscape_fullscreen&&window.screen&&window.screen.orientation){api.on("fullscreen",function(a,api){if(typeof api.video.width!="undefined"&&typeof api.video.height!="undefined"&&(api.video.width!=0&&api.video.height!=0&&api.video.width<api.video.height)){screen.orientation.lock("portrait-primary")}else{screen.orientation.lock("landscape-primary")}})}});flowplayer(function(api,root){root=jQuery(root);var hlsjs,player,audioUXGroup,audioGroups,hls_audio_button,hls_audio_menu,mse=window.MediaSource||window.WebKitMediaSource;flowplayer.engine("hlsjs-lite").plugin(function(params){hlsjs=params.hls});api.bind("ready",function(e,api){removeAudioMenu();if(hlsjs&&api.video.type=="application/x-mpegurl"){parseAudioTracksHlsJs(hlsjs);createAudioMenu()}});api.one("progress",function(){if(api.engine.engineName=="html5"&&api.video.type=="application/x-mpegurl"){parseAudioTracksSafari();createAudioMenu()}});function getVideoTagAudioTracks(){var video=root.find("video");if(video.length&&video[0].audioTracks){return video[0].audioTracks}return[]}function hilightAudioTrack(audioTrack){if(!audioTrack.name)audioTrack.name=audioTrack.label;root.find(".fv-fp-hls-menu a").each(function(k,el){jQuery(el).toggleClass("fp-selected",jQuery(el).attr("data-audio")===audioTrack.name)})}function createAudioMenu(){if(!audioUXGroup||audioUXGroup.length<2){return}hls_audio_button=jQuery('<strong class="fv-fp-hls">'+fv_flowplayer_translations.audio_button+"</strong>");hls_audio_menu=jQuery('<div class="fp-menu fv-fp-hls-menu"></div>').insertAfter(root.find(".fp-controls"));hls_audio_menu.append("<strong>"+fv_flowplayer_translations.audio_menu+"</strong>");audioUXGroup.forEach(function(audioTrack){hls_audio_menu.append('<a data-audio="'+audioTrack.name+'" data-lang="'+audioTrack.lang+'">'+audioTrack.name+"</a>")});hls_audio_button.insertAfter(root.find(".fp-controls .fp-volume")).on("click",function(e){e.preventDefault();e.stopPropagation();if(hls_audio_menu.hasClass("fp-active")){api.hideMenu(hls_audio_menu[0])}else{root.click();api.showMenu(hls_audio_menu[0])}});jQuery("a",hls_audio_menu).on("click",function(e){var adata=e.target.getAttribute("data-audio");if(hlsjs){var gid=hlsjs.audioTracks[hlsjs.audioTrack].groupId;var atrack=hlsjs.audioTracks.filter(function(at){return at.groupId===gid&&(at.name===adata||at.lang===adata)})[0];hlsjs.audioTrack=atrack.id;hilightAudioTrack(atrack)}else{var tracks=getVideoTagAudioTracks();for(var i in tracks){if(!tracks.hasOwnProperty(i))continue;if(tracks[i].label==adata){tracks[i].enabled=true;hilightAudioTrack(tracks[i])}}}});if(hlsjs){hilightAudioTrack(hlsjs.audioTracks[hlsjs.audioTrack])}else{var tracks=getVideoTagAudioTracks();for(var i in tracks){if(!tracks.hasOwnProperty(i))continue;if(tracks[i].enabled){hilightAudioTrack(tracks[i])}}}}function removeAudioMenu(){jQuery(hls_audio_menu).remove();jQuery(hls_audio_button).remove()}function parseAudioTracksHlsJs(data){audioGroups=[];audioUXGroup=[];data.levels.forEach(function(level){var agroup=level.attrs.AUDIO;if(agroup&&audioGroups.indexOf(agroup)<0){audioGroups.push(agroup)}if(audioGroups.length){audioUXGroup=data.audioTracks.filter(function(audioTrack){return audioTrack.groupId===audioGroups[0]})}})}function parseAudioTracksSafari(){audioGroups=[];audioUXGroup=[];var tracks=getVideoTagAudioTracks();for(var i in tracks){if(!tracks.hasOwnProperty(i))continue;audioUXGroup.push({id:tracks[i].id,name:tracks[i].label})}}});flowplayer(function(api,root){var store_engine_pos=-1;var store_engine=false;api.on("error",function(e,api,err){if(err.code!=4||api.engine.engineName!="hlsjs")return;console.log("FV Player: HLSJS failed to play the video, switching to Flash HLS");api.error=api.loading=false;jQuery(root).removeClass("is-error");jQuery(flowplayer.engines).each(function(k,v){if(flowplayer.engines[k].engineName=="hlsjs"){store_engine_pos=k;store_engine=flowplayer.engines[k];delete flowplayer.engines[k]}});var index=typeof api.video.index!="undefined"?api.video.index:0;var video=index>0?api.conf.playlist[index].sources:api.conf.clip.sources;video.index=index;api.load({sources:video});api.bind("unload error",function(){flowplayer.engines[store_engine_pos]=store_engine})})});flowplayer(function(api,root){var initialDelay=api.conf.live_stream_reload?api.conf.live_stream_reload:30,continueDelay=10,useDelay=initialDelay,retryLabel=fv_flowplayer_translations.live_stream_retry,timer;api.clearLiveStreamCountdown=function(){if(timer){clearInterval(timer);api.error=api.loading=false;jQuery(root).removeClass("is-error");jQuery(root).find(".fp-message.fp-shown").remove();api.unload()}};api.conf.flashls={manifestloadmaxretry:2};api.on("ready",function(){useDelay=initialDelay;retryLabel=fv_flowplayer_translations.live_stream_retry}).on("progress",function(){useDelay=continueDelay;retryLabel=fv_flowplayer_translations.live_stream_continue;clearInterval(timer)});api.on("error",function(e,api,err){setTimeout(function(){if(!api.conf.clip.live&&!api.conf.live&&!(err.video&&err.video.src.match(/\/\/vimeo.com\/event\//)))return;var delay=useDelay;if(api.conf.clip.streaming_time){delay=api.conf.clip.streaming_time-Math.floor(Date.now()/1e3)}else if(api.conf.clip.live_starts_in){delay=api.conf.clip.live_starts_in}var startLabel=fv_flowplayer_translations.live_stream_starting.replace(/%d/,secondsToDhms(delay));retryLabel=retryLabel.replace(/%d/,secondsToDhms(delay));var message=api.conf.clip.live_starts_in?startLabel:retryLabel;clearInterval(timer);if(err.code===1||err.code===2||err.code===4){root.className+=" is-offline";if(flowplayer.support.flashVideo){api.one("flashdisabled",function(){root.querySelector(".fp-flash-disabled").style.display="none"})}var messageElement=root.querySelector(".fp-ui .fp-message");messageElement.innerHTML=message;var reload_delay=delay>300?300:delay;timer=setInterval(function(){reload_delay-=1;delay-=1;if(reload_delay>0&&messageElement){messageElement.querySelector("span").innerHTML=secondsToDhms(delay)}else{clearInterval(timer);if(!api.error){return}api.error=api.loading=false;messageElement=root.querySelector(".fp-ui .fp-message");if(messageElement){root.querySelector(".fp-ui").removeChild(messageElement)}root.className=root.className.replace(/\bis-(error|offline)\b/g,"");api.load()}},1e3)}},1)});function secondsToDhms(seconds){seconds=Number(seconds);var d=Math.floor(seconds/(3600*24));var h=Math.floor(seconds%(3600*24)/3600);var m=Math.floor(seconds%3600/60);var s=Math.floor(seconds%60);var t=fv_flowplayer_translations;var output=d>0?d==1?t.duration_1_day.replace(/%s/,d):t.duration_n_days.replace(/%s/,d):"";if(output&&h>0)output+=", ";output+=h>0?h==1?t.duration_1_hour.replace(/%s/,h):t.duration_n_hours.replace(/%s/,h):"";if(output&&m>0)output+=", ";output+=m>0?m==1?t.duration_1_minute.replace(/%s/,m):t.duration_n_minutes.replace(/%s/,m):"";if(output&&s>0)output+=t.and;output+=s>0?s==1?t.duration_1_second.replace(/%s/,s):t.duration_n_seconds.replace(/%s/,s):"";return output}});flowplayer(function(api,root){root=jQuery(root);var hlsjs;flowplayer.engine("hlsjs-lite").plugin(function(params){hlsjs=params.hls});api.on("ready",function(e,api){if(hlsjs&&api.conf.playlist.length&&api.engine.engineName!="hlsjs-lite"){hlsjs.destroy()}})});flowplayer(function(api,root){if(!flowplayer.support.browser.safari&&!flowplayer.support.iOS)return;root=jQuery(root);var video_tag=false,did_start_playing=false,are_waiting_already=0;api.on("ready",function(e,api,video){are_waiting_already=0;did_start_playing=false;if(api.engine.engineName=="html5"&&video.src.match(/\?/)){video_tag=root.find("video");if(!video_tag.data("fv-ios-recovery")){video_tag.on("waiting",wait_for_stalled);video_tag.data("fv-ios-recovery",true)}api.one("progress",function(){did_start_playing=true})}});api.bind("beforeseek",wait_for_stalled);function debug(e){console.log("FV Player: iOS video element: "+e.type)}function wait_for_stalled(){if(!did_start_playing){return}if(video_tag&&api.engine.engineName=="html5"){are_waiting_already++;if(are_waiting_already>1){if(are_waiting_already>3){console.log("FV Player: iOS video element needs a push, triggering 'stalled'");video_tag.trigger("stalled")}return}console.log("FV Player: iOS video element will trigger error after 'stalled' arrives");video_tag.one("stalled",function(){var time=api.video.time;if(api.video.type.match(/video\//)){console.log("FV Player: Running check of video file...");var test_video=document.createElement("video");test_video.src=api.video.src;test_video.onloadedmetadata=function(){are_waiting_already=0;console.log("FV Player: Video link works")};test_video.onerror=function(){console.log("FV Player: Video link issue!");if(are_waiting_already>0){api.trigger("error",[api,{code:4,video:api.video}])}};return}setTimeout(function(){console.log(api.video.time,time);if(api.video.time!=time){console.log("FV Player: iOS video element continues playing, no need for error");return}if(api.paused){console.log("FV Player: iOS video element paused, no need for error");return}api.trigger("error",[api,{code:4,video:api.video}])},5e3)})}}});!function(e){var n=!1;if("function"==typeof define&&define.amd&&(define(e),n=!0),"object"==typeof exports&&(module.exports=e(),n=!0),!n){var o=window.Cookies,t=window.Cookies=e();t.noConflict=function(){return window.Cookies=o,t}}}(function(){function e(){for(var e=0,n={};e<arguments.length;e++){var o=arguments[e];for(var t in o)n[t]=o[t]}return n}function n(o){function t(n,r,i){var c;if("undefined"!=typeof document){if(arguments.length>1){if("number"==typeof(i=e({path:"/"},t.defaults,i)).expires){var a=new Date;a.setMilliseconds(a.getMilliseconds()+864e5*i.expires),i.expires=a}i.expires=i.expires?i.expires.toUTCString():"";try{c=JSON.stringify(r),/^[\{\[]/.test(c)&&(r=c)}catch(e){}r=o.write?o.write(r,n):encodeURIComponent(r+"").replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),n=(n=(n=encodeURIComponent(n+"")).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent)).replace(/[\(\)]/g,escape);var s="";for(var f in i)i[f]&&(s+="; "+f,!0!==i[f]&&(s+="="+i[f]));return document.cookie=n+"="+r+s}n||(c={});for(var p=document.cookie?document.cookie.split("; "):[],d=/(%[0-9A-Z]{2})+/g,u=0;u<p.length;u++){var l=p[u].split("="),C=l.slice(1).join("=");this.json||'"'!==C.charAt(0)||(C=C.slice(1,-1));try{var m=l[0].replace(d,decodeURIComponent);if(C=o.read?o.read(C,m):o(C,m)||C.replace(d,decodeURIComponent),this.json)try{C=JSON.parse(C)}catch(e){}if(n===m){c=C;break}n||(c[m]=C)}catch(e){}}return c}}return t.set=t,t.get=function(e){return t.call(t,e)},t.getJSON=function(){return t.apply({json:!0},[].slice.call(arguments))},t.defaults={},t.remove=function(n,o){t(n,"",e(o,{expires:-1}))},t.withConverter=n,t}return n(function(){})});flowplayer.bean.off(document,"keydown.fp");flowplayer(function(api,root){var bean=flowplayer.bean;if(!api.conf.keyboard)return;bean.on(root,"mouseenter mouseleave",function(e){fv_player_focused=!api.disabled&&e.type=="mouseover"?api:0;if(fv_player_focused)fv_player_focusedRoot=root});api.bind("ready",function(e,api,video){if(video.subtitles&&video.subtitles.length>0){var help=jQuery(root).find(".fp-help").html();help+='<div class="fp-help-section fp-help-subtitles"><p><em>c</em>cycle through subtitles</p></div>';jQuery(root).find(".fp-help").html(help)}else{jQuery(root).find(".fp-help-subtitles").remove()}})});flowplayer.bean.on(document,"keydown.fp",function(e){if(typeof fv_player_focused=="undefined")return;var api=fv_player_focused,focusedRoot=api?fv_player_focusedRoot:false,common=flowplayer.common;var el=api&&!api.disabled?api:0,metaKeyPressed=e.ctrlKey||e.metaKey||e.altKey,key=e.which,conf=el&&el.conf;if(common.hasClass(focusedRoot,"no-controlbar")||common.hasClass(focusedRoot,"is-cva"))return;if(!el||!conf.keyboard||el.disabled)return;if([63,187,191].indexOf(key)!=-1){common.toggleClass(focusedRoot,"is-help");return false}if(key==27&&common.hasClass(focusedRoot,"is-help")){common.toggleClass(focusedRoot,"is-help");return false}if(!metaKeyPressed&&el.ready){e.preventDefault();if(e.shiftKey){if(key==39)el.speed(true);else if(key==37)el.speed(false);else if(key==78)el.next();else if(key==80)el.prev();return}if(key<58&&key>47)return el.seekTo(key-48);switch(key){case 38:case 75:el.volume(el.volumeLevel+.15);break;case 40:case 74:el.volume(el.volumeLevel-.15);break;case 39:case 76:el.seeking=true;el.seek(api.video.time+5);break;case 37:case 72:el.seeking=true;el.seek(api.video.time-5);break;case 190:el.seekTo();break;case 32:el.toggle();break;case 70:if(conf.fullscreen)el.fullscreen();break;case 77:el.mute();break;case 81:el.unload();break;case 67:if(!api.video.subtitles||api.video.subtitles.length==0)break;var current_subtitles=jQuery(focusedRoot).find(".fp-dropdown li.active[data-subtitle-index]").data("subtitle-index");if(typeof current_subtitles=="undefined")current_subtitles=-1;current_subtitles++;if(current_subtitles>api.video.subtitles.length-1){current_subtitles=-1}api.trigger("fv-subtitles-switched");if(current_subtitles>-1){el.loadSubtitles(current_subtitles);fv_player_notice(focusedRoot,fv_flowplayer_translations.subtitles_switched+" "+api.video.subtitles[current_subtitles].label,"fv-subtitles-switched")}else{el.disableSubtitles();fv_player_notice(focusedRoot,fv_flowplayer_translations.subtitles_disabled,"fv-subtitles-switched")}break}}});flowplayer(function(api,root){root=jQuery(root);if(window.learndash_video_data&&learndash_video_data.videos_found_provider=="local"&&root.closest("[data-video-progression=true]").length){LearnDash_disable_assets(true);LearnDash_watchPlayers();api.on("finish",function(e,api,time){if(typeof api.video.click=="string"){return}window.LearnDash_disable_assets(false)})}});flowplayer(function(api,root){api.bind("load",function(e,api,data){var player=jQuery(e.currentTarget);if(player.data("live")){var live_check=setTimeout(function(){player.find(".fp-ui").append('<div class="fp-message">'+fv_flowplayer_translations.live_stream_failed+"</div>");player.addClass("is-error")},1e4);jQuery(e.currentTarget).data("live_check",live_check)}}).bind("ready",function(e,api,data){clearInterval(jQuery(e.currentTarget).data("live_check"))}).bind("error",function(e,api,data){var player=jQuery(e.currentTarget);if(player.data("live")){player.find(".fp-message").html(fv_flowplayer_translations.live_stream_failed_2)}})});(function($){flowplayer(function(api,root){if(jQuery(root).hasClass("is-cva"))return;$(document).on("submit","#"+jQuery(root).attr("id")+" .mailchimp-form",function(e){e.preventDefault();$(".mailchimp-response",root).remove();$("input[type=submit]",root).attr("disabled","disabled").addClass("fv-form-loading");var data={action:"fv_wp_flowplayer_email_signup"};$("[name]",this).each(function(){data[this.name]=$(this).val()});$.post(fv_player.ajaxurl,data,function(response){response=JSON.parse(response);$('<div class="mailchimp-response"></div>').insertAfter(".mailchimp-form",root);if(response.text.match(/already subscribed/)){response.status="ERROR"}if(response.status==="OK"){$(".mailchimp-form input[type=text],.mailchimp-form input[type=email]",root).val("");$(".mailchimp-response",root).removeClass("is-fv-error").html(response.text);setTimeout(function(){$(".wpfp_custom_popup",root).fadeOut()},2e3)}else{$(".mailchimp-response",root).addClass("is-fv-error").html(response.text)}$("input[type=submit]",root).removeAttr("disabled").removeClass("fv-form-loading")})})})})(jQuery);function fv_flowplayer_mobile_switch(id){var regex=new RegExp("[\\?&]fv_flowplayer_mobile=([^&#]*)");var results=regex.exec(location.search);if((results!=null&&results[1]=="yes"||(jQuery(window).width()<=480||jQuery(window).height()<=480))&&(results==null||results[1]!="no")){var fv_fp_mobile=false;jQuery("#wpfp_"+id+" video source").each(function(){if(jQuery(this).attr("id")!="wpfp_"+id+"_mobile"){fv_fp_mobile=true;jQuery(this).remove()}});if(fv_fp_mobile){jQuery("#wpfp_"+id).after('<p class="fv-flowplayer-mobile-switch">'+fv_flowplayer_translations.mobile_browser_detected_1+' <a href="'+document.URL+'?fv_flowplayer_mobile=no">'+fv_flowplayer_translations.mobile_browser_detected_2+"</a>.</p>")}}}if(typeof fv_flowplayer_mobile_switch_array!="undefined"){for(var fv_flowplayer_mobile_switch_i in fv_flowplayer_mobile_switch_array){if(!fv_flowplayer_mobile_switch_array.hasOwnProperty(fv_flowplayer_mobile_switch_i))continue;fv_flowplayer_mobile_switch(fv_flowplayer_mobile_switch_i)}}flowplayer(function(api,root){if(!flowplayer.support.touch)return;jQuery.fn.fv_single_double_click=function(single_click_callback,double_click_callback,timeout){return this.each(function(){var clicks=0,self=this;jQuery(this).on("click",function(event){clicks++;if(clicks==1){setTimeout(function(){if(clicks==1){single_click_callback.call(self,event)}else{double_click_callback.call(self,event)}clicks=0},timeout||300)}})})};root=jQuery(root);var left=jQuery('<div class="fv-fp-tap-left"><span>-10s</span></div>'),right=jQuery('<div class="fv-fp-tap-right"><span>+10s</span></div>');left.fv_single_double_click(function(){api.toggle()},function(e){maybe_seek(e,left,api.ready?api.video.time-10:false)});right.fv_single_double_click(function(){api.toggle()},function(e){maybe_seek(e,right,api.ready?api.video.time+10:false)});root.find(".fp-ui").append(left).append(right);function maybe_seek(e,el,time){if(api.ready){api.seek(time);animation(el)}else{api.toggle()}e.preventDefault()}function animation(el){el.addClass("is-active");setTimeout(function(){el.removeClass("is-active")},500)}});flowplayer(function(api,root){root=jQuery(root);var instance_id=root.data("flowplayer-instance-id");flowplayer.audible_instance=-1;api.one("load",function(){setTimeout(function(){api.conf.splash=false},0)});api.on("ready",function(){var is_muted=root.data("volume")==0;if(!is_muted){flowplayer.audible_instance=instance_id}jQuery(".flowplayer[data-flowplayer-instance-id]").each(function(){var player=jQuery(this).data("flowplayer");var current_instance_id=jQuery(this).data("flowplayer-instance-id");if(flowplayer.audible_instance==-1||current_instance_id==flowplayer.audible_instance||current_instance_id==instance_id)return;if(player){if(player.ready){if(api.conf.multiple_playback){if(!is_muted){player.mute(true,true)}}else if(player.playing){player.pause()}}else{player.clearLiveStreamCountdown();player.unload()}}})}).on("mute",function(e,api,muted){if(!muted&&flowplayer.audible_instance!=instance_id){flowplayer(flowplayer.audible_instance).mute(true,true);flowplayer.audible_instance=instance_id}}).on("resume",function(){if(!api.muted){flowplayer.audible_instance=instance_id}if(!api.conf.multiple_playback){jQuery(".flowplayer[data-flowplayer-instance-id]").each(function(){if(instance_id==jQuery(this).data("flowplayer-instance-id"))return;var player=jQuery(this).data("flowplayer");if(player&&player.playing){player.pause()}})}})});function fv_flowplayer_browser_ff_m4v(hash){if(flowplayer.support.browser&&flowplayer.support.browser.mozilla&&navigator.appVersion.indexOf("Win")!=-1){jQuery("#wpfp_"+hash).attr("data-engine","flash")}}if(typeof fv_flowplayer_browser_ff_m4v_array!="undefined"){for(var fv_flowplayer_browser_ff_m4v_i in fv_flowplayer_browser_ff_m4v_array){if(!fv_flowplayer_browser_ff_m4v_array.hasOwnProperty(fv_flowplayer_browser_ff_m4v_i))continue;fv_flowplayer_browser_ff_m4v(fv_flowplayer_browser_ff_m4v_i)}}function fv_flowplayer_browser_chrome_fail(hash,sAttributes,sVideo,bAutobuffer){jQuery("#wpfp_"+hash).bind("error",function(e,api,error){if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&error!=null&&(error.code==3||error.code==4||error.code==5)){api.unload();jQuery("#wpfp_"+hash).attr("id","bad_wpfp_"+hash);jQuery("#bad_wpfp_"+hash).after('<div id="wpfp_'+hash+'" '+sAttributes+' data-engine="flash"></div>');jQuery("#wpfp_"+hash).flowplayer({playlist:[[{mp4:sVideo}]]});if(bAutobuffer){jQuery("#wpfp_"+hash).bind("ready",function(e,api){api.play()})}else{jQuery("#wpfp_"+hash).flowplayer().play(0)}jQuery("#bad_wpfp_"+hash).remove()}})}if(typeof fv_flowplayer_browser_chrome_fail_array!="undefined"){for(var fv_flowplayer_browser_chrome_fail_i in fv_flowplayer_browser_chrome_fail_array){if(!fv_flowplayer_browser_chrome_fail_array.hasOwnProperty(fv_flowplayer_browser_chrome_fail_i))continue;fv_flowplayer_browser_chrome_fail(fv_flowplayer_browser_chrome_fail_i,fv_flowplayer_browser_chrome_fail_array[fv_flowplayer_browser_chrome_fail_i]["attrs"],fv_flowplayer_browser_chrome_fail_array[fv_flowplayer_browser_chrome_fail_i]["mp4"],fv_flowplayer_browser_chrome_fail_array[fv_flowplayer_browser_chrome_fail_i]["auto_buffer"])}}function fv_flowplayer_browser_ie(hash){if(flowplayer.support.browser&&flowplayer.support.browser.msie&&parseInt(flowplayer.support.browser.version,10)>=9||!!navigator.userAgent.match(/Trident.*rv[ :]*11\./)){jQuery("#wpfp_"+hash).attr("data-engine","flash")}}if(typeof fv_flowplayer_browser_ie_array!="undefined"){for(var fv_flowplayer_browser_ie_i in fv_flowplayer_browser_ie_array){if(!fv_flowplayer_browser_ie_array.hasOwnProperty(fv_flowplayer_browser_ie_i))continue;fv_flowplayer_browser_ie(fv_flowplayer_browser_ie_i)}}function fv_flowplayer_browser_chrome_mp4(hash){var match=window.navigator.appVersion.match(/Chrome\/(\d+)\./);if(match!=null){var chrome_ver=parseInt(match[1],10);if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&chrome_ver<28&&navigator.appVersion.indexOf("Win")!=-1||/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&chrome_ver<27&&navigator.appVersion.indexOf("Linux")!=-1&&navigator.userAgent.toLowerCase().indexOf("android")==-1){jQuery("#wpfp_"+hash).attr("data-engine","flash")}}}if(navigator.platform.indexOf("iPhone")!=-1||navigator.platform.indexOf("iPod")!=-1||navigator.platform.indexOf("iPad")!=-1||navigator.userAgent.toLowerCase().indexOf("android")!=-1){flowplayer(function(api,root){api.bind("error",function(e,api,error){if(error.code==10){jQuery(e.target).find(".fp-message").html(fv_flowplayer_translations.unsupported_format)}})})}jQuery(document).ready(function(){if(navigator.platform.indexOf("iPhone")!=-1||navigator.platform.indexOf("iPod")!=-1||navigator.platform.indexOf("iPad")!=-1){jQuery(window).trigger("load")}jQuery(".flowplayer").on("mouseleave",function(){jQuery(this).find(".fvp-share-bar").removeClass("visible");jQuery(this).find(".embed-code").hide()})});if(typeof flowplayer!=="undefined"){flowplayer(function(api,root){root=jQuery(root);var notice=false,hlsjs;flowplayer.engine("hlsjs-lite").plugin(function(params){hlsjs=params.hls});var playlist=api.conf.playlist.length?api.conf.playlist:[api.conf.clip];if(playlist[0]&&playlist[0].pending_encoding){show_notice(playlist[0])}api.on("load",function(e,api,video){if(video.pending_encoding){show_notice(video);if(hlsjs){hlsjs.destroy()}return false}remove_notice()});function show_notice(video){remove_notice();var title="Video is being processed",message="Please return later to see the actual video in this player.";if(video.pending_encoding_error){title="Video unavailable";message="There was an error in the video encoding."}else if(video.pending_encoding_progress){message+="<br /><br />("+video.pending_encoding_progress+" done)"}notice=jQuery('<div class="fv-player-encoder-video-processing-modal"><div><h2>'+title+"</h2><p>"+message+"</p></div></div");root.append(notice)}function remove_notice(){if(notice){notice.remove()}}})}if(!Date.now){Date.now=function(){return(new Date).getTime()}}(function($){var sendPositionsEvery=60,ajaxCall=null,maxCookieSize=2500,localStorageEnabled=null,cookiePositionsKeyName="video_positions",cookiePlaylistsKeyName="player_playlist_item",tempPositionCookieKeyName="video_positions_tmp",tempTopPositionCookieKeyName="video_top_positions_tmp",tempPlaylistsCookieKeyName="player_playlist_item_tmp",tempSawCookieKeyName="video_saw_tmp",playPositions=[],playTopPositions=[],playlistIndexes=[],sawVideo=[],getSerialized=function(data){var serialized=JSON.stringify(data),dataSize=getTextByteSize(serialized);if(dataSize>maxCookieSize){while(dataSize>maxCookieSize){for(var i in data){if(!data.hasOwnProperty(i))continue;delete data[i];serialized=JSON.stringify(data);dataSize=getTextByteSize(serialized);break}}}return serialized},getVideoId=function(video){if(video.id){return video.id}var out=typeof video.sources_original!="undefined"&&typeof video.sources_original[0]!="undefined"?video.sources_original[0].src:video.sources[0].src;if(typeof video.sources_original=="undefined"||typeof video.sources_original[0]=="undefined"){out=removeAWSSignatures(out)}return out},getTextByteSize=function(txt){return encodeURIComponent(txt).length},getCookieKey=function(key){return localStorageEnabled?localStorage.getItem(key):Cookies.get(key)},setCookieKey=function(key,value){return localStorageEnabled?localStorage.setItem(key,value):Cookies.set(key,value)},removeCookieKey=function(key){if(localStorageEnabled){localStorage.removeItem(key)}{Cookies.remove(key)}},removeVideoPosition=function(e,api){if(api.video.sources){var video_id=getVideoId(api.video);playPositions[video_id]=0;playTopPositions[video_id]=0;sawVideo[video_id]=1}},removeAWSSignatures=function(videoURL){return videoURL.replace(/(X-Amz-Algorithm=[^&]+&?)/gm,"").replace(/(X-Amz-Credential=[^&]+&?)/gm,"").replace(/(X-Amz-Date=[^&]+&?)/gm,"").replace(/(X-Amz-Expires=[^&]+&?)/gm,"").replace(/(X-Amz-SignedHeaders=[^&]+&?)/gm,"").replace(/(X-Amz-Signature=[^&]+&?)/gm,"")},sendVideoPositions=function(async,callback){var beaconSupported="sendBeacon"in navigator;if(async!==true){async=false}if(!callback||typeof callback=="undefined"){callback=function(){}}postDataPositions=[];postDataPlaylists=[];for(var video_name in playPositions){if(!playPositions.hasOwnProperty(video_name))continue;postDataPositions.push({name:video_name,position:playPositions[video_name],top_position:playTopPositions[video_name],saw:typeof sawVideo[video_name]!="undefined"?sawVideo[video_name]:false})}for(var player_id in playlistIndexes){if(!playlistIndexes.hasOwnProperty(player_id))continue;postDataPlaylists.push({player:player_id,item:playlistIndexes[player_id]})}if(!postDataPlaylists.length){removeCookieKey(tempPlaylistsCookieKeyName)}if(!postDataPositions.length){removeCookieKey(tempPositionCookieKeyName);removeCookieKey(tempTopPositionCookieKeyName);removeCookieKey(tempSawCookieKeyName);return}if(flowplayer.conf.is_logged_in=="1"){if(beaconSupported){try{var temp_position_data={},temp_top_position_data={},temp_saw_data={},temp_playlist_data={};for(var i in postDataPositions){if(!postDataPositions.hasOwnProperty(i))continue;var name=postDataPositions[i].name;temp_position_data[name]=postDataPositions[i].position;temp_top_position_data[name]=postDataPositions[i].top_position;temp_saw_data[name]=postDataPositions[i].saw}for(var i in postDataPlaylists){if(!postDataPlaylists.hasOwnProperty(i))continue;temp_playlist_data[postDataPlaylists[i].player]=postDataPlaylists[i].item}setCookieKey(tempPositionCookieKeyName,getSerialized(temp_position_data));setCookieKey(tempTopPositionCookieKeyName,getSerialized(temp_top_position_data));setCookieKey(tempSawCookieKeyName,getSerialized(temp_saw_data));setCookieKey(tempPlaylistsCookieKeyName,getSerialized(temp_playlist_data))}catch(e){return}var fd=new FormData;fd.append("action","fv_wp_flowplayer_video_position_save");fd.append("videoTimes",encodeURIComponent(JSON.stringify(postDataPositions)));fd.append("playlistItems",encodeURIComponent(JSON.stringify(postDataPlaylists)));navigator.sendBeacon(fv_player.ajaxurl,fd);return false}else{return jQuery.ajax({type:"POST",async:async,url:fv_player.ajaxurl,complete:callback,data:{action:"fv_wp_flowplayer_video_position_save",videoTimes:postDataPositions,playlistItems:postDataPlaylists}})}}else{try{var data_positions=getCookieKey(cookiePositionsKeyName);var data_playlist_item=getCookieKey(cookiePlaylistsKeyName);if(data_positions&&typeof data_positions!=="undefined"){data_positions=JSON.parse(data_positions)}else{data_positions={}}if(data_playlist_item&&typeof data_playlist_item!=="undefined"){data_playlist_item=JSON.parse(data_playlist_item)}else{data_playlist_item={}}for(var i in postDataPositions){if(!postDataPositions.hasOwnProperty(i))continue;data_positions[postDataPositions[i].name]=postDataPositions[i].position}for(var i in postDataPlaylists){if(!postDataPlaylists.hasOwnProperty(i))continue;data_playlist_item[postDataPlaylists[i].player]=postDataPlaylists[i].item}var serialized_positions=JSON.stringify(data_positions),serialized_playlist_items=JSON.stringify(data_playlist_item),dataSize_postions=getTextByteSize(serialized_positions),dataSize_playlist_items=getTextByteSize(serialized_playlist_items);if(dataSize_postions>maxCookieSize){while(dataSize_postions>maxCookieSize){for(var i in data_positions){if(!data_positions.hasOwnProperty(i))continue;delete data_positions[i];serialized_positions=JSON.stringify(data_positions);dataSize_postions=getTextByteSize(serialized_positions);break}}}if(dataSize_playlist_items>maxCookieSize){while(dataSize_playlist_items>maxCookieSize){for(var i in data_positions){if(!data_playlist_item.hasOwnProperty(i))continue;delete data_playlist_item[i];serialized_playlist_items=JSON.stringify(data_playlist_item);dataSize_playlist_items=getTextByteSize(serialized_positions);break}}}setCookieKey(cookiePositionsKeyName,serialized_positions);setCookieKey(cookiePlaylistsKeyName,serialized_playlist_items)}catch(e){return}}return false};flowplayer(function(api,root){if(typeof api.conf.disable_localstorage!="undefined"){return}var $root=jQuery(root),enabled=flowplayer.conf.video_position_save_enable&&$root.data("save-position")!=false||$root.data("save-position"),progressEventsCount=0,player_id=$root.data("player-id")?$root.data("player-id"):false,item_changed=false,getVideoPosition=function(api){var video_id=getVideoId(api.video),position=api.video.position;if(flowplayer.conf.is_logged_in!="1"){var data=getCookieKey(cookiePositionsKeyName);if(data&&typeof data!=="undefined"){try{data=JSON.parse(data);if(data[video_id]){position=data[video_id]}}catch(e){return}}}if(!!api.get_custom_end&&api.get_custom_end()<position){position=false}if(!!api.get_custom_start&&api.get_custom_start()>0){if(position<api.get_custom_start()){position=false}}return position},isSupported=function(){return!(api.live||api.video&&typeof api.video.click=="string")},seekIntoPosition=function(e,api){if(!isSupported())return;var position=getVideoPosition(api);if(position){seek(position)}},storeVideoPosition=function(e,api){if(!isSupported()){return}if(api.video.sources){var video_id=getVideoId(api.video),position=Math.round(api.video.time);playPositions[video_id]=position;if(typeof playTopPositions[video_id]=="undefined"){var stored_top_position=0;if(api.conf.playlist){stored_top_position=api.conf.playlist[api.video.index]&&api.conf.playlist[api.video.index].sources[0]&&api.conf.playlist[api.video.index].sources[0].top_position?api.conf.playlist[api.video.index].sources[0].top_position:0}else{stored_top_position=api.conf.clip.sources[0]&&api.conf.clip.sources[0].top_position?api.conf.clip.sources[0].top_position:0}playTopPositions[video_id]=stored_top_position}else if(playTopPositions[video_id]<position){playTopPositions[video_id]=position}if(api.conf.playlist.length>0){if(player_id)playlistIndexes[player_id]=api.video.index}if(progressEventsCount++>=sendPositionsEvery&&flowplayer.conf.closingPage){if(ajaxCall){ajaxCall.abort()}ajaxCall=sendVideoPositions(true,function(){ajaxCall=null});progressEventsCount=0}}},forceSavePosition=function(e,api){var inPlaylist=false;for(var i in api.conf.playlist){if(!api.conf.playlist.hasOwnProperty(i))continue;inPlaylist=true;break}if(inPlaylist&&!flowplayer.conf.closingPage){progressEventsCount=sendPositionsEvery+1;storeVideoPosition(e,api);sendVideoPositions()}},seek=function(position){if(!!api.custom_seek){api.custom_seek(position);return}var seek_count=0;var do_seek=setInterval(function(){if(++seek_count>20)clearInterval(do_seek);if(api.loading)return;api.seek(parseInt(position));clearInterval(do_seek)},10)},processTempData=function(temp_data_name,video_id){var data=getCookieKey(temp_data_name),output=false;if(data&&typeof data!=="undefined"){try{data=JSON.parse(data);if(typeof data[video_id]!="undefined"){output=data[video_id];delete data[video_id];var stillHasData=false;for(var i in data){if(!data.hasOwnProperty(i))continue;stillHasData=true;break}if(stillHasData){setCookieKey(temp_data_name,JSON.stringify(data))}else{removeCookieKey(temp_data_name)}}return output}catch(e){}}},restorePlaylistItem=function(e,api){if(typeof api=="undefined"||api.conf.playlist.length==0)return;var item_index=-1;if(player_id){if(flowplayer.conf.is_logged_in!="1"){var data=getCookieKey(cookiePlaylistsKeyName);if(data&&typeof data!=="undefined"){try{data=JSON.parse(data);if(data[player_id]){item_index=data[player_id]}}catch(e){return}}}else if(flowplayer.conf.is_logged_in=="1"){item_index=api.conf.playlist.length>0?processTempData(tempPlaylistsCookieKeyName,player_id):false}}if(item_index>=0&&!item_changed){if(api.video&&api.video.type!="video/youtube"){api.play(item_index)}item_changed=true;$root.data("position_changed",1)}};if(!enabled)return;if(getCookieKey(tempPlaylistsCookieKeyName)){$root.removeData("playlist_start")}api.bind("finish",removeVideoPosition);api.on("ready",function(){api.one("progress",seekIntoPosition)});api.bind("progress",storeVideoPosition);api.bind("unload",function(){item_changed=false;api.one("ready",restorePlaylistItem)});api.one("ready",restorePlaylistItem);jQuery(".fp-ui",root).on("click",function(){restorePlaylistItem()});api.playlist_thumbnail_progress=function(el,video,position){if(!!api.get_custom_start&&api.get_custom_start(video)>0){position-=api.get_custom_start(video);if(position<0)position=0}var duration=video.duration;if(!!api.get_custom_duration&&api.get_custom_duration()>0){duration=api.get_custom_duration()}if(!duration){duration=el.data("duration")}if(!duration)return;var progress=100*position/duration;el.css("width",progress+"%")};if(flowplayer.conf.is_logged_in=="1"){var is_playlist=api.conf.playlist.length>0,playlist=is_playlist?api.conf.playlist:[api.conf.clip],playlist_external=jQuery("[rel="+jQuery(root).attr("id")+"]");for(var i in playlist){if(!playlist.hasOwnProperty(i))continue;var video_id=getVideoId(playlist[i]),position=processTempData(tempPositionCookieKeyName,video_id),top_position=processTempData(tempTopPositionCookieKeyName,video_id),saw=processTempData(tempSawCookieKeyName,video_id);if(position){if(is_playlist){api.conf.playlist[i].sources[0].position=position;var playlist_progress=jQuery("a",playlist_external).eq(i).find(".fvp-progress");if(playlist_progress.length){api.playlist_thumbnail_progress(playlist_progress,api.conf.playlist[i],position)}}else{api.conf.clip.sources[0].position=position}}if(top_position){if(!playlist[i].sources[0].top_position||playlist[i].sources[0].top_position<top_position){if(is_playlist){api.conf.playlist[i].sources[0].top_position=top_position}else{api.conf.clip.sources[0].top_position=top_position}}}if(saw){if(is_playlist){api.conf.playlist[i].sources[0].saw=true}else{api.conf.clip.sources[0].saw=true}}}}api.bind("finish",function(e,api){if(api.conf.playlist.length){api.conf.playlist[api.video.index].sources[0].saw=true}else{api.conf.clip.sources[0].saw=true}})});jQuery(window).on("beforeunload pagehide",function(){if(!flowplayer.conf.closingPage){flowplayer.conf.closingPage=true;sendVideoPositions()}});if(typeof fv_flowplayer_conf.disable_localstorage!="undefined"){localStorageEnabled=false}if(localStorageEnabled!==null){return localStorageEnabled}localStorageEnabled=true;try{localStorage.setItem("t","t");if(localStorage.getItem("t")!=="t"){localStorageEnabled=false}localStorage.removeItem("t")}catch(e){localStorageEnabled=false}})(jQuery);flowplayer(function(api,root){root=jQuery(root);if(api.conf.playlist.length==0)return;var real_videos=0;jQuery(api.conf.playlist).each(function(k,v){if(typeof v.click=="undefined"){real_videos++}});if(real_videos<2)return;var playlist=jQuery(".fp-playlist-external[rel="+root.attr("id")+"]");var playlist_button=jQuery('<strong class="fv-fp-list">Item 1.</strong>'),playlist_button_name=jQuery('<strong class="fv-fp-list-name">Item 1.</strong>'),playlist_menu=jQuery('<div class="fp-menu fv-fp-list-menu"></div>').insertAfter(root.find(".fp-controls"));var i=0,item_index=[],track_item=[];jQuery(api.conf.playlist).each(function(k,v){if(typeof v.click=="undefined"){var title=parse_title(playlist.find("h4").eq(i));playlist_menu.append('<a data-index="'+k+'">'+(i+1)+". "+title+"</a>");track_item[k]=title;item_index.push(k);i++}});function playlist_button_click(e){e.preventDefault();e.stopPropagation();if(playlist_menu.hasClass("fp-active")){api.hideMenu(playlist_menu[0])}else{root.trigger("click");api.showMenu(playlist_menu[0])}}playlist_button.insertAfter(root.find(".fp-controls .fp-volume")).on("click",playlist_button_click);playlist_button_name.insertAfter(playlist_button).on("click",playlist_button_click);jQuery("a",playlist_menu).on("click",function(){if(typeof api.conf.playlist[jQuery(this).data("index")-1]!="undefined"&&typeof api.conf.playlist[jQuery(this).data("index")-1].click!="undefined"){api.play(jQuery(this).data("index")-1)}else{api.play(jQuery(this).data("index"))}});api.on("ready",function(e,api,video){playlist_menu.find("a").removeClass("fp-selected");var thumb=playlist_menu.find("a[data-index="+video.index+"]");thumb.addClass("fp-selected");var label=fv_flowplayer_translations.playlist_item_no;label=label.replace(/%d/,item_index.indexOf(video.index)+1);label=label.replace(/%s/,parse_title(thumb.find("h4")));playlist_button.html(label);playlist_button_name.html(item_index.indexOf(video.index)+1+". "+track_item[video.index])});function parse_title(el){var tmp=el.clone();tmp.find("i.dur").remove();return tmp.text()}});flowplayer(function(api,root){root=jQuery(root);var playlist=api.conf.playlist,videoIndex;api.bind("load",function(e,api,video){videoIndex=video.index});api.bind("error",function(e,api,error){setTimeout(function(){if(playlist.length>0&&api.error==true){videoIndex=api.video.index;if(api.conf.video_checker=="1"&&playlist[videoIndex].video_checker&&playlist[videoIndex].video_checker.length>0){console.log("FV Player: Video checker message present, stopping auto-advance to next playlist item");return false}api.error=api.loading=false;root.removeClass("is-error");root.find(".fp-message.fp-shown").remove();videoIndex++;if(videoIndex>playlist.length-1){videoIndex=0}console.log("FV Player: Playlist item failure, auto-advancing to "+(videoIndex+1)+". item");api.play(videoIndex)}},1e3)})});flowplayer(function(api,root){root=jQuery(root);var original_prev,original_next,random_seed;if(!root.data("button-no_picture")&&!root.data("button-repeat")&&!root.data("button-rewind"))return;api.bind("ready",function(e,api){if(typeof original_next=="undefined"&&typeof original_prev=="undefined"){original_next=api.next;original_prev=api.prev}if(!api.video.type.match(/^audio/)&&root.data("button-no_picture")&&root.find(".fv-fp-no-picture").length==0){var button_no_picture=jQuery('<span class="fv-fp-no-picture"><svg viewBox="0 0 90 80" width="18px" height="18px" class="fvp-icon fvp-nopicture"><use xlink:href="#fvp-nopicture"></use></svg></span>');button_no_picture.insertAfter(root.find(".fp-controls .fp-volume")).on("click",function(e){e.preventDefault();e.stopPropagation();jQuery(".fp-engine",root).slideToggle(20);jQuery(this).toggleClass("is-active fp-color-fill")})}if(root.data("button-repeat")){if(api.conf.playlist.length>0&&root.find(".fv-fp-playlist").length==0){var t=fv_flowplayer_translations,playlist_button=jQuery('<strong class="fv-fp-playlist mode-normal"> <svg viewBox="0 0 80.333 80" width="18px" height="18px" class="fvp-icon fvp-replay-list"><title>'+t.playlist_replay_all+'</title><use xlink:href="#fvp-replay-list"></use></svg> <svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-shuffle"><title>'+t.playlist_shuffle+'</title><use xlink:href="#fvp-shuffle"></use></svg> <svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-replay-track"><title>'+t.playlist_replay_video+'</title><use xlink:href="#fvp-replay-track"></use></svg> <span id="fvp-playlist-play" title="'+t.playlist_play_all+'">'+t.playlist_play_all_button+"</span> </strong>"),playlist_menu=jQuery('<div class="fp-menu fv-fp-playlist-menu"> <a data-action="repeat_playlist"><svg viewBox="0 0 80.333 80" width="18px" height="18px" class="fvp-icon fvp-replay-list"><title>'+t.playlist_replay_all+'</title><use xlink:href="#fvp-replay-list"></use></svg> <span class="screen-reader-text">'+t.playlist_replay_all+'</span></a> <a data-action="shuffle_playlist"><svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-shuffle"><title>'+t.playlist_shuffle+'</title><use xlink:href="#fvp-shuffle"></use></svg> <span class="screen-reader-text">'+t.playlist_shuffle+'</span></a> <a data-action="repeat_track"><svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-replay-track"><title>'+t.playlist_replay_video+'</title><use xlink:href="#fvp-replay-track"></use></svg> <span class="screen-reader-text">'+t.playlist_replay_video+'</span></a> <a class="fp-selected" data-action="normal"><span id="fvp-playlist-play" title="'+t.playlist_play_all+'">'+t.playlist_play_all_button+"</span></a> </div>").insertAfter(root.find(".fp-controls"));api.conf.playlist_shuffle=api.conf.track_repeat=false;random_seed=randomize();var should_advance=api.conf.advance;playlist_button.insertAfter(root.find(".fp-controls .fp-volume")).on("click",function(e){e.preventDefault();e.stopPropagation();if(playlist_menu.css("right")!=="auto"){playlist_menu.css({right:"auto",left:playlist_button.position().left+"px"})}if(playlist_menu.hasClass("fp-active")){api.hideMenu(playlist_menu[0])}else{root.trigger("click");api.showMenu(playlist_menu[0])}});jQuery("a",playlist_menu).on("click",function(){jQuery(this).siblings("a").removeClass("fp-selected");jQuery(this).addClass("fp-selected");playlist_button.removeClass("mode-normal mode-repeat-track mode-repeat-playlist mode-shuffle-playlist");var action=jQuery(this).data("action");if(action=="repeat_playlist"){playlist_button.addClass("mode-repeat-playlist");api.conf.loop=true;api.conf.advance=true;api.video.loop=api.conf.track_repeat=false;api.conf.playlist_shuffle=false}else if(action=="shuffle_playlist"){playlist_button.addClass("mode-shuffle-playlist");api.conf.loop=true;api.conf.advance=true;api.conf.playlist_shuffle=true}else if(action=="repeat_track"){playlist_button.addClass("mode-repeat-track");api.conf.track_repeat=api.video.loop=true;api.conf.loop=api.conf.playlist_shuffle=false}else if(action=="normal"){playlist_button.addClass("mode-normal");api.conf.track_repeat=api.video.loop=false;api.conf.loop=api.conf.playlist_shuffle=false}if(api.conf.playlist_shuffle){api.next=function(){api.play(random_seed.pop());if(random_seed.length==0)random_seed=randomize()};api.prev=function(){api.play(random_seed.shift());if(random_seed.length==0)random_seed=randomize()}}else{api.next=original_next;api.prev=original_prev}});if(api.conf.loop){jQuery("a[data-action=repeat_playlist]",playlist_menu).trigger("click")}api.on("progress",function(){api.video.loop=api.conf.track_repeat});api.on("finish.pl",function(e,api){console.log("playlist_repeat",api.conf.loop,"advance",api.conf.advance,"video.loop",api.video.loop);if(api.conf.playlist_shuffle){api.play(random_seed.pop());if(random_seed.length==0)random_seed=randomize()}})}else if(root.find(".fv-fp-track-repeat").length==0&&api.conf.playlist.length==0){var button_track_repeat=jQuery('<strong class="fv-fp-track-repeat"><svg viewBox="0 0 80.333 71" width="18px" height="18px" class="fvp-icon fvp-replay-track"><use xlink:href="#fvp-replay-track"></use></svg></strong>');button_track_repeat.insertAfter(root.find(".fp-controls .fp-volume")).on("click",function(e){e.preventDefault();e.stopPropagation();jQuery(this).toggleClass("is-active fp-color-fill",api.video.loop);if(api.video.loop){api.video.loop=false}else{api.video.loop=true}});if(api.conf.loop){button_track_repeat.addClass("is-active fp-color-fill")}}}if(root.data("button-rewind")){if(root.find(".fv-fp-rewind").length==0){var button_rewind=jQuery('<span class="fv-fp-rewind"><svg viewBox="0 0 24 24" width="21px" height="21px" class="fvp-icon fvp-rewind"><use xlink:href="#fvp-rewind"></use></svg></span>');button_rewind.insertBefore(root.find(".fp-controls .fp-playbtn")).on("click",function(e){e.preventDefault();e.stopPropagation();api.seek(api.video.time-10)});button_rewind.toggle(!api.video.live)}if(root.find(".fv-fp-forward").length==0){var button_forward=jQuery('<span class="fv-fp-forward"><svg viewBox="0 0 24 24" width="21px" height="21px" class="fvp-icon fvp-forward"><use xlink:href="#fvp-forward"></use></svg></span>');button_forward.insertAfter(root.find(".fp-controls .fp-playbtn")).on("click",function(e){e.preventDefault();e.stopPropagation();api.seek(api.video.time+10)});button_forward.toggle(!api.video.live)}}}).bind("unload",function(){root.find(".fv-fp-no-picture").remove();root.find(".fv-fp-playlist").remove();root.find(".fv-fp-track-repeat").remove()});function array_shuffle(a){var j,x,i;for(i=a.length;i;i--){j=Math.floor(Math.random()*i);x=a[i-1];a[i-1]=a[j];a[j]=x}return a}function randomize(random_seed){random_seed=[];jQuery(api.conf.playlist).each(function(k,v){random_seed.push(k)});random_seed=array_shuffle(random_seed);console.log("FV Player Randomizer random seed:",random_seed);return random_seed}});flowplayer(function(api,root){var $root=jQuery(root),start_index=$root.data("playlist_start");if(typeof start_index=="undefined")return;function start_position_changer(){if($root.data("position_changed")!==1&&api.conf.playlist.length){start_index--;if(typeof api.conf.playlist[start_index].click=="undefined"){api.play(start_index)}$root.data("position_changed",1)}}api.bind("unload",function(){start_index=$root.data("playlist_start");$root.removeData("position_changed");api.one("ready",start_position_changer)});api.one("ready",start_position_changer);jQuery(".fp-ui",root).on("click",function(){start_position_changer();$root.data("position_changed",1)})});document.addEventListener("custombox:overlay:close",function(e){console.log("FV Player: Custombox/Popup anything ligtbox closed");var $players=jQuery(this).find(".flowplayer");if($players.length==0)return;console.log("FV Player: Custombox/Popup anything ligtbox contains a player");$players.each(function(index,player){var api=jQuery(player).data("flowplayer");if(typeof api!="undefined"){if(api.playing){console.log("FV Player: Custombox/Popup anything ligtbox video pause");api.pause()}else if(api.loading){api.one("ready",function(){console.log("FV Player: Custombox/Popup anything ligtbox video unload");api.unload()})}}})});flowplayer(function(api,root){api.bind("finish",function(){var finished_at=api.video.time;if(api.video.loop){api.one("pause",function(){if(finished_at<=api.video.time){api.resume()}})}})});function fv_flowplayer_amazon_s3(hash,time){jQuery("#wpfp_"+hash).bind("error",function(e,api,error){var fv_fp_date=new Date;if(error.code==4&&fv_fp_date.getTime()>fv_fp_utime+parseInt(time)){jQuery(e.target).find(".fp-message").delay(500).queue(function(n){jQuery(this).html(fv_flowplayer_translations.video_expired);n()})}})}flowplayer(function(api,root){root=jQuery(root);root.find(".fp-logo").removeAttr("href");if(root.hasClass("no-controlbar")){var timelineApi=api.sliders.timeline;timelineApi.disable(true);api.bind("ready",function(){timelineApi.disable(true)})}jQuery(".fvfp_admin_error",root).remove();root.find(".fp-logo, .fp-header").on("click",function(e){if(e.target!==this)return;root.find(".fp-ui").trigger("click")});jQuery(".fvp-share-bar .sharing-facebook",root).append('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#fff"><title>Facebook</title><path d="M11.9 5.2l-2.6 0 0-1.6c0-0.7 0.3-0.7 0.7-0.7 0.3 0 1.6 0 1.6 0l0-2.9 -2.3 0c-2.6 0-3.3 2-3.3 3.3l0 2 -1.6 0 0 2.9 1.6 0c0 3.6 0 7.8 0 7.8l3.3 0c0 0 0-4.2 0-7.8l2.3 0 0.3-2.9Z"/></svg>');jQuery(".fvp-share-bar .sharing-twitter",root).append('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#fff"><title>Twitter</title><path d="M16 3.1c-0.6 0.3-1.2 0.4-1.9 0.5 0.7-0.4 1.2-1 1.4-1.8 -0.6 0.4-1.3 0.6-2.1 0.8 -0.6-0.6-1.4-1-2.4-1 -2 0.1-3.2 1.6-3.2 4 -2.7-0.1-5.1-1.4-6.7-3.4 -0.9 1.4 0.2 3.8 1 4.4 -0.5 0-1-0.1-1.5-0.4l0 0.1c0 1.6 1.1 2.9 2.6 3.2 -0.7 0.2-1.3 0.1-1.5 0.1 0.4 1.3 1.6 2.2 3 2.3 -1.6 1.7-4.6 1.4-4.8 1.3 1.4 0.9 3.2 1.4 5 1.4 6 0 9.3-5 9.3-9.3 0-0.1 0-0.3 0-0.4 0.6-0.4 1.2-1 1.6-1.7Z"/></svg>');jQuery(".fvp-share-bar .sharing-email",root).append('<svg xmlns="http://www.w3.org/2000/svg" height="16" viewBox="0 0 16 16" width="16" fill="#fff"><title>Email</title><path d="M8 10c0 0 0 0-1 0L0 6v7c0 1 0 1 1 1h14c1 0 1 0 1-1V6L9 10C9 10 8 10 8 10zM15 2H1C0 2 0 2 0 3v1l8 4 8-4V3C16 2 16 2 15 2z"/></svg>');jQuery(".fp-header",root).prepend(jQuery(".fvp-share-bar",root));if(api.conf.playlist.length){var show=true;var playlist=api.conf.playlist;if(playlist.length==2){if(typeof playlist[0].click!="undefined"&&typeof playlist[1].click=="undefined"){show=false}if(typeof playlist[0].click=="undefined"&&typeof playlist[1].click!="undefined"){show=false}}else if(playlist.length==3){if(typeof playlist[0].click!="undefined"&&typeof playlist[1].click=="undefined"&&typeof playlist[2].click!="undefined"){show=false}}if(show){var prev=jQuery('<a class="fp-icon fv-fp-prevbtn"></a>');var next=jQuery('<a class="fp-icon fv-fp-nextbtn"></a>');root.find(".fp-controls .fp-playbtn").before(prev).after(next);prev.on("click",function(){api.trigger("prev",[api]);api.prev()});next.on("click",function(){api.trigger("next",[api]);api.next()})}}if(typeof fv_player_editor_conf!="undefined"){root.on("click",".fvp-sharing > li",function(e){e.preventDefault();fv_player_notice(root,fv_player_editor_translations.link_notice,2e3);return false})}api.bind("pause resume finish unload ready",function(e,api){root.addClass("no-brand")});api.one("ready",function(){root.find(".fp-fullscreen").clone().appendTo(root.find(".fp-controls"))});api.on("ready",function(e,api,video){setTimeout(function(){jQuery(".fvp-share-bar",root).show();jQuery(".fv-player-buttons-wrap",root).appendTo(jQuery(".fv-player-buttons-wrap",root).parent().find(".fp-ui"))},100)});api.bind("finish",function(){var url=root.data("fv_redirect");if(url&&(typeof api.video.is_last=="undefined"||api.video.is_last)){location.href=url}});if(flowplayer.support.iOS&&flowplayer.support.iOS.version==11){api.bind("error",function(e,api,error){if(error.code==4)root.find(".fp-engine").hide()})}jQuery(document).on("contextmenu",".flowplayer",function(e){e.preventDefault()});api.one("ready",function(e,api,video){root.find(".fp-chromecast").insertAfter(root.find(".fp-header .fp-fullscreen"))});root.find(".fp-waiting").html('<div class="fp-preload"><b></b><b></b><b></b><b></b></div>');var id=root.attr("id"),alternative=!flowplayer.conf.native_fullscreen&&flowplayer.conf.mobile_alternative_fullscreen,events_enter="fakefullscreen",events_exit="fakefullscreen-exit";if(!flowplayer.support.fullscreen){events_enter+=" fullscreen";events_exit+=" fullscreen-exit"}api.bind(events_enter,function(e,api){jQuery("#wpadminbar, .nc_wrapper").hide();if(alternative||e.type=="fakefullscreen"){if(api.video.type=="video/youtube")return;root.before('<span data-fv-placeholder="'+id+'"></span>');root.appendTo("body")}});api.bind(events_exit,function(e,api,video){jQuery("#wpadminbar, .nc_wrapper").show();if(alternative||e.type=="fakefullscreen-exit"){jQuery("span[data-fv-placeholder="+id+"]").replaceWith(root)}})});(function(){var extension=function(flowplayer){flowplayer(function(api,root){if(!jQuery(root).data("speedb"))return;var support=flowplayer.support;if(!support.video||!support.inlineVideo)return;var common=flowplayer.common,bean=flowplayer.bean,ui=common.find(".fp-ui",root)[0],controlbar=common.find(".fp-controls",ui)[0],speeds=api.conf.speeds;bean.on(root,"click",".fp-speed",function(){var menu=common.find(".fp-speed-menu",root)[0];if(common.hasClass(menu,"fp-active"))api.hideMenu();else api.showMenu(menu)});bean.on(root,"click",".fp-speed-menu a",function(ev){var s=ev.target.getAttribute("data-speed");api.speed(s)});api.on("speed",function(ev,_a,rate){if(speeds.length>1){selectSpeed(rate)}}).on("ready",function(ev,api){removeMenu();if(flowplayer.support.android&&api.engine.engineName=="html5"&&api.video.type=="application/x-mpegurl")return;speeds=api.conf.speeds;if(speeds.length>1){createMenu()}});function removeMenu(){common.find(".fp-speed-menu",root).forEach(common.removeNode);common.find(".fp-speed",root).forEach(common.removeNode)}function round(val){return Math.round(val*100)/100}function createMenu(){controlbar.appendChild(common.createElement("strong",{className:"fp-speed"},api.currentSpeed+"x"));var menu=common.createElement("div",{className:"fp-menu fp-speed-menu",css:{width:"auto"}},"<strong>Speed</strong>");speeds.forEach(function(s){var a=common.createElement("a",{"data-speed":round(s)},round(s)+"x");menu.appendChild(a)});ui.appendChild(menu);selectSpeed(api.currentSpeed);jQuery(root).find(".fp-speed-menu strong").text(fv_flowplayer_translations.speed)}function selectSpeed(rate){common.find(".fp-speed",root)[0].innerHTML=rate+"x";common.find(".fp-speed-menu a",root).forEach(function(el){common.toggleClass(el,"fp-selected",el.getAttribute("data-speed")==rate);common.toggleClass(el,"fp-color",el.getAttribute("data-speed")==rate)})}})};if(typeof module==="object"&&module.exports)module.exports=extension;else if(typeof window.flowplayer==="function")extension(window.flowplayer)})();flowplayer(function(api,root){if(typeof fv_flowplayer_conf.disable_localstorage!="undefined"){return}api.on("speed",function(ev,_a,rate){try{window.localStorage.fv_player_speed=rate}catch(e){}});api.on("ready",function(){if(window.localStorage.fv_player_speed&&jQuery(root).find("strong.fp-speed").is(":visible")){api.speed(parseFloat(window.localStorage.fv_player_speed))}if(jQuery(root).data("volume")==0){api.mute(true,true)}})});flowplayer(function(api,root){root=jQuery(root);var last_tracked=-1;if(!api.conf.fv_stats||!api.conf.fv_stats.enabled&&(!root.data("fv_stats")||root.data("fv_stats")=="no"))return;api.on("ready finish",function(e,api){api.one("progress",function(e,api){if(root.data("fv_stats_data")){try{var player_post_data=root.data("fv_stats_data")}catch(e){return false}if(last_tracked==get_index())return;last_tracked=get_index();jQuery.post(api.conf.fv_stats.url,{blog_id:api.conf.fv_stats.blog_id,video_id:api.video.id?api.video.id:0,player_id:player_post_data.player_id,post_id:player_post_data.post_id,tag:"play"})}})}).on("finish",function(){last_tracked=-1});function get_index(){return api.video.index?api.video.index:0}});flowplayer(function(api,root){var $root=jQuery(root);var $playerDiv=$root.find(".fp-player");var sticky=$root.data("fvsticky");var globalSticky=false;var videoRatio=$root.data("ratio");api.is_sticky=false;if(typeof videoRatio=="undefined"){videoRatio=.5625}if(flowplayer.conf.sticky_video==1&&typeof sticky=="undefined"){globalSticky=true}if(globalSticky||sticky){if(flowplayer.support.firstframe){var stickyPlace=flowplayer.conf.sticky_place;var stickyWidth=flowplayer.conf.sticky_width;if(stickyWidth==""){stickyWidth=380}var stickyHeight=stickyWidth*videoRatio;fv_player_sticky_video()}else{return}}function fv_player_sticky_video(){var $window=jQuery(window),$flowplayerDiv=$root,top=$flowplayerDiv.offset().top,offset=Math.floor(top+$flowplayerDiv.outerHeight()/2);api.on("unload",function(){fv_player_sticky_class_remove();$root.removeClass("is-unSticky")});$window.on("resize",function(){if(!is_big_enough()){if(api.is_sticky){fv_player_sticky_class_remove()}return}top=$flowplayerDiv.offset().top;offset=Math.floor(top+$flowplayerDiv.outerHeight()/2)}).on("scroll",function(){if(!is_big_enough()){if(api.is_sticky){fv_player_sticky_class_remove()}return}top=$flowplayerDiv.offset().top;offset=Math.floor(top+$flowplayerDiv.outerHeight()/2);if($window.scrollTop()>offset&&(api.loading||flowplayer.audible_instance==$root.data("flowplayer-instance-id"))){if(jQuery("div.flowplayer.is-unSticky").length>0){return false}else{fv_player_sticky_class_add()}}else{fv_player_sticky_class_remove()}})}function fv_player_sticky_class_add(){if($playerDiv.hasClass("is-sticky-"+stickyPlace)){return}else{$playerDiv.addClass("is-sticky");$playerDiv.addClass("is-sticky-"+stickyPlace);if($root.find("a.fp-sticky").length==0){$root.find("div.fp-header").prepend('<a class="fp-sticky fp-icon"></a>')}$playerDiv.css("width",stickyWidth);$playerDiv.css("height",stickyHeight);$playerDiv.css("max-height",stickyHeight);api.is_sticky=true;api.trigger("sticky",[api])}$playerDiv.parent(".flowplayer").addClass("is-stickable")}function fv_player_sticky_class_remove(){$playerDiv.removeClass("is-sticky");$playerDiv.removeClass("is-sticky-"+stickyPlace);$playerDiv.css("width","");$playerDiv.css("height","");$playerDiv.css("max-height","");$playerDiv.parent(".flowplayer").removeClass("is-stickable");if(api.is_sticky){api.is_sticky=false;api.trigger("sticky-exit",[api])}}function is_big_enough(){return jQuery(window).innerWidth()>=fv_flowplayer_conf.sticky_min_width}api.sticky=function(flag,remember){if(typeof flag=="undefined"){flag=!api.is_sticky}if(remember){$root.toggleClass("is-unSticky",!flag)}if(flag){fv_player_sticky_class_add()}else{fv_player_sticky_class_remove()}}});jQuery(function($){$(document).on("click","a.fp-sticky",function(){var root=$("div.flowplayer.is-stickable"),api=root.data("flowplayer");root.addClass("is-unSticky");var $playerDiv=root.find(".fp-player");$playerDiv.removeClass("is-sticky");$playerDiv.removeClass("is-sticky-right-bottom");$playerDiv.removeClass("is-sticky-left-bottom");$playerDiv.removeClass("is-sticky-right-top");$playerDiv.removeClass("is-sticky-left-top");$playerDiv.css("width","");$playerDiv.css("height","");$playerDiv.css("max-height","");if(api.is_sticky){api.is_sticky=false;api.trigger("sticky-exit",[api])}});$(document).on("click","div.flowplayer.is-unSticky",function(){$("div.flowplayer").removeClass("is-unSticky")})});flowplayer(function(api,root){root=jQuery(root);if(typeof fv_flowplayer_conf.disable_localstorage!="undefined"){return}var ls=window.localStorage;api.on("ready",function(e,api,video){if(root.find("strong.fp-cc").is(":visible")){if(ls.fv_player_subtitle&&api.video.subtitles.length){if(ls.fv_player_subtitle==="none"){api.disableSubtitles()}else{api.video.subtitles.forEach(function(item,index){if(item.srclang===ls.fv_player_subtitle){api.loadSubtitles(index)}})}}else{var defaultSubtitle=video.subtitles.filter(function(one){return one["fv_default"]})[0];if(defaultSubtitle){api.loadSubtitles(video.subtitles.indexOf(defaultSubtitle))}}}root.find(".fp-subtitle-menu").on("click",function(e){var subtitle_index=e.target.getAttribute("data-subtitle-index");if(typeof subtitle_index=="string"){try{ls.fv_player_subtitle=subtitle_index>-1?api.video.subtitles[subtitle_index].srclang:"none"}catch(e){}}})})});flowplayer(function(api,root){root=jQuery(root);var currentPoint,check=false;api.bind("cuepoint",function(e,api,cue){check=false;if(cue.subtitle){currentPoint=cue.index}});api.on("ready",function(e,api){root.find(".fp-subtitle-menu strong").text(fv_flowplayer_translations.closed_captions);root.find('.fp-subtitle-menu a[data-subtitle-index="-1"]').text(fv_flowplayer_translations.no_subtitles)});root.on("click",".fp-subtitle-menu a[data-subtitle-index]",function(e){if(jQuery(this).data("subtitle-index")>-1){check=true;api.on("progress",time_check)}});function time_check(e,api,time){if(check){(api.cuepoints||[]).forEach(function(cue,index){var entry=cue.subtitle;if(entry&&currentPoint!=index){if(time>=cue.time&&(!entry.endTime||time<=entry.endTime)){api.trigger("cuepoint",[api,cue])}}})}}});if(typeof flowplayer!=="undefined"&&typeof fv_flowplayer_conf!="undefined"&&fv_flowplayer_conf.video_hash_links){flowplayer(function(api,root){if(jQuery(root).find(".sharing-link").length>0){var abEnd,abStart,hash,sTime,abloop;function update_link(abStartNew,abEndNew){hash=fv_player_get_video_link_hash(api);sTime=","+fv_player_time_hms(api.video.time);if(abStartNew&&abEndNew){abStart=","+fv_player_time_hms_ms(abStartNew+api.get_custom_start());abEnd=","+fv_player_time_hms_ms(abEndNew+api.get_custom_start())}else{abEnd=abloop&&typeof api.get_ab_end()!="undefined"&&api.get_ab_end()?","+fv_player_time_hms_ms(api.get_ab_end()):"";abStart=abloop&&typeof api.get_ab_start()!="undefined"&&api.get_ab_start()?","+fv_player_time_hms_ms(api.get_ab_start()):""}jQuery(".sharing-link",root).attr("href",jQuery(".sharing-link",root).attr("href").replace(/#.*/,"")+"#"+hash+sTime+abStart+abEnd)}api.on("ready",function(e,api,video){if(!api.fv_noUiSlider)return;api.fv_noUiSlider.on("set",function(values){update_link(values[0],values[1])})});api.on("progress",function(e,api){if(!api.video.sources||!api.video.sources[0]){return}update_link()});api.on("abloop",function(e,api,active){abloop=active;if(!api.playing){update_link()}});jQuery(".sharing-link",root).on("click",function(e){fv_player_clipboard(jQuery(this).attr("href"),function(){e.preventDefault();fv_player_notice(root,fv_flowplayer_translations.link_copied,2e3)})})}});jQuery(document).on("click",'a[href*="fvp_"]',function(){var link=jQuery(this);setTimeout(function(){if(link.parents(".fvp-share-bar").length==0)fv_autoplay_exec()})})}flowplayer(function(api,root){root=jQuery(root);var bean=flowplayer.bean;var restore=flowplayer.conf.default_volume;if(restore==0){restore="0.5"}root.on("mousedown touchstart",".fp-volumebtn",function(e){var volumebtn=jQuery(this);if(api.volumeLevel==0){volumebtn.one("click",function(){api.volume(restore);return false})}});root.on("mousedown touchstart mouseup touchend",".fp-volumebar",function(e){if(api.volumeLevel!=0){restore=api.volumeLevel}});api.on("volume",function(e,api){if(root.hasClass("is-mouseover")&&!api.muted){if(api.volumeLevel==0){bean.off(flowplayer.support.touch?root:document,"mousemove.sld touchmove.sld");api.mute(true)}}});var deal_with_muted_start=false;api.one("ready",function(e,api){if(root.hasClass("is-audio"))return;deal_with_muted_start=true});api.on("progress",function(e,api,time){if(deal_with_muted_start&&time>1){deal_with_muted_start=false;var video=jQuery("root").find("video");if(video.length&&!hasAudio(video[0])){return}if(api.muted||api.volumeLevel==0){if(localStorage.muted=="true"||localStorage.volume=="0"){return}var mute_notice=jQuery('<div class="fp-message fp-message-muted"><span class="fp-icon fp-volumebtn-notice"></span> '+fv_flowplayer_translations.click_to_unmute+"</div>");mute_notice.on("click touchstart",function(){api.mute(false);api.volume(1)});root.find(".fp-ui").append(mute_notice);root.addClass("has-fp-message-muted");setTimeout(remove_volume_notice,5e3)}}});api.on("mute volume",function(){if(!api.muted||api.volumeLevel>0){remove_volume_notice()}});function remove_volume_notice(){root.removeClass("has-fp-message-muted");root.find(".fp-message-muted").remove()}function hasAudio(video){return video.mozHasAudio||Boolean(video.webkitAudioDecodedByteCount)||Boolean(video.audioTracks&&video.audioTracks.length)}});if(typeof flowplayer!="undefined"){flowplayer(function(api,root){root=jQuery(root);if(navigator.userAgent.match(/iPhone.* OS [0-6]_/i)){api.one("progress",function(e){if(typeof api.video.subtitles!=="undefined"&&api.video.subtitles.length){fv_player_warning(root,fv_flowplayer_translations.warning_iphone_subs)}})}if(flowplayer.support.android&&flowplayer.support.android.version<5&&(flowplayer.support.android.samsung||flowplayer.support.browser.safari)){fv_player_warning(root,fv_flowplayer_translations.warning_unstable_android,"firefox")}if(/Android 4/.test(navigator.userAgent)&&!/Firefox/.test(navigator.userAgent)){api.on("ready",function(e,api,video){setTimeout(function(){if(video.src&&video.src.match(/fpdl.vimeocdn.com/)&&(video.time==0||video.time==1)){fv_player_warning(root,fv_flowplayer_translations.warning_unstable_android,"firefox");api.on("progress",function(e,api){root.prev().find(".fv-player-warning-firefox").remove()})}},1500)});api.on("error",function(e,api,error){if(error.MEDIA_ERR_NETWORK==2&&error.video.src.match(/fpdl.vimeocdn.com/)){fv_player_warning(root,fv_flowplayer_translations.warning_unstable_android,"firefox")}})}if(/Safari/.test(navigator.userAgent)&&/Version\/5/.test(navigator.userAgent)){api.on("error",function(e,api,error){if(error.video.src.match(/fpdl.vimeocdn.com/)){fv_player_warning(root,fv_flowplayer_translations.warning_old_safari)}})}var sup=flowplayer.support;if(sup.android&&(sup.android.samsung&&parseInt(sup.browser.version)<66||sup.browser.safari)){api.on("error",function(e,api,error){fv_player_warning(root,fv_flowplayer_translations.warning_samsungbrowser,"warning_samsungbrowser")})}});function fv_player_warning(root,warning,classname){var wrapper=jQuery(root).prev(".fv-player-warning-wrapper");if(wrapper.length==0){jQuery(root).before('<div class="fv-player-warning-wrapper">');wrapper=jQuery(root).prev(".fv-player-warning-wrapper")}if(wrapper.find(".fv-player-warning-"+classname).length==0){var latest=jQuery("<p style='display: none' "+(classname?" class='fv-player-warning-"+classname+"'":"")+">"+warning+"</p>");wrapper.append(latest);latest.slideDown()}}}
flowplayer/modules/appearance.module.js CHANGED
@@ -61,6 +61,12 @@ flowplayer(function(api, root) {
61
 
62
  jQuery(window).on('resize',check_size);
63
 
 
 
 
 
 
 
64
  api.on('ready fullscreen fullscreen-exit sticky sticky-exit', function(e) {
65
  setTimeout( function() {
66
  buttons_count = root.find('.fp-controls > strong:visible').length + root.find('.fp-controls > .fp-icon:visible').length;
61
 
62
  jQuery(window).on('resize',check_size);
63
 
64
+ if ('fonts' in document) {
65
+ api.one('load', function() {
66
+ document.fonts.load('1em flowplayer');
67
+ });
68
+ }
69
+
70
  api.on('ready fullscreen fullscreen-exit sticky sticky-exit', function(e) {
71
  setTimeout( function() {
72
  buttons_count = root.find('.fp-controls > strong:visible').length + root.find('.fp-controls > .fp-icon:visible').length;
flowplayer/modules/compatibility.module.js CHANGED
@@ -71,6 +71,17 @@ function fv_flowplayer_safety_resize() {
71
  while( jQuery(el).width() < 30 || jQuery(el).width() == jQuery(this).width() ) {
72
  if( jQuery(el).parent().length == 0 ) break;
73
  el = jQuery(el).parent();
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
 
76
  jQuery(this).width( jQuery(el).width() );
71
  while( jQuery(el).width() < 30 || jQuery(el).width() == jQuery(this).width() ) {
72
  if( jQuery(el).parent().length == 0 ) break;
73
  el = jQuery(el).parent();
74
+
75
+ // LearnDash sets the parent DIV height to 0 and uses padding-top: 56.25% to make up some space
76
+ // So we avoid that here as otherwise the player would not appear!
77
+ if( el.hasClass('ld-video') ) {
78
+ if( el[0].style.height == '' ) {
79
+ el.css('height','auto');
80
+ }
81
+ if( parseInt( el.css('padding-bottom') ) > 0 ) {
82
+ el.css('padding-bottom', '0');
83
+ }
84
+ }
85
  }
86
 
87
  jQuery(this).width( jQuery(el).width() );
flowplayer/modules/fv-player.js CHANGED
@@ -334,8 +334,17 @@ function fv_player_preload() {
334
 
335
  // Show splash img if audio
336
  if( !video.is_audio_stream && !video.type.match(/^audio/) ) {
337
- splash_img.remove();
338
- splash_text.remove();
 
 
 
 
 
 
 
 
 
339
  }
340
  } );
341
 
@@ -910,6 +919,10 @@ function fv_autoplay_exec(){
910
  autoplay = root.attr('data-fvautoplay');
911
 
912
  if( !fv_player_did_autoplay && autoplay ) {
 
 
 
 
913
  if( ( flowplayer.support.android || flowplayer.support.iOS ) && api && api.conf.clip.sources[0].type == 'video/youtube' ) {
914
  // don't let these mobile devices autoplay YouTube
915
  console.log( 'FV Player: Autoplay for YouTube not supported on Android and iOS');
@@ -982,9 +995,23 @@ function fv_player_notice(root, message, timeout) {
982
 
983
 
984
  var fv_player_clipboard = function(text, successCallback, errorCallback) {
 
 
 
 
 
 
 
 
 
 
985
  try {
986
- fv_player_doCopy(text);
987
- successCallback();
 
 
 
 
988
  } catch (e) {
989
  if( typeof(errorCallback) != "undefined" ) errorCallback(e);
990
  }
@@ -1020,7 +1047,6 @@ function fv_player_doCopy(text) {
1020
 
1021
  try {
1022
  var result = document.execCommand('copy');
1023
-
1024
  // Restore previous selection.
1025
  if (selected) {
1026
  document.getSelection().removeAllRanges();
334
 
335
  // Show splash img if audio
336
  if( !video.is_audio_stream && !video.type.match(/^audio/) ) {
337
+
338
+ // Ensure the splash is only removed once the video really really starts playing when using autoplay
339
+ if( window.fv_player_pro && window.fv_player_pro.autoplay_scroll || root.data('fvautoplay') ) {
340
+ api.one('progress', function() {
341
+ splash_img.remove();
342
+ splash_text.remove();
343
+ });
344
+ } else {
345
+ splash_img.remove();
346
+ splash_text.remove();
347
+ }
348
  }
349
  } );
350
 
919
  autoplay = root.attr('data-fvautoplay');
920
 
921
  if( !fv_player_did_autoplay && autoplay ) {
922
+ if( autoplay == -1 ) {
923
+ return;
924
+ }
925
+
926
  if( ( flowplayer.support.android || flowplayer.support.iOS ) && api && api.conf.clip.sources[0].type == 'video/youtube' ) {
927
  // don't let these mobile devices autoplay YouTube
928
  console.log( 'FV Player: Autoplay for YouTube not supported on Android and iOS');
995
 
996
 
997
  var fv_player_clipboard = function(text, successCallback, errorCallback) {
998
+ if( navigator.clipboard && typeof(navigator.clipboard.writeText) == "function" ) {
999
+ navigator.clipboard.writeText(text).then(function() {
1000
+ successCallback();
1001
+ }, function() {
1002
+ errorCallback();
1003
+ }
1004
+ );
1005
+ return;
1006
+ }
1007
+
1008
  try {
1009
+ if( fv_player_doCopy(text) ) {
1010
+ successCallback();
1011
+ } else {
1012
+ errorCallback();
1013
+ }
1014
+
1015
  } catch (e) {
1016
  if( typeof(errorCallback) != "undefined" ) errorCallback(e);
1017
  }
1047
 
1048
  try {
1049
  var result = document.execCommand('copy');
 
1050
  // Restore previous selection.
1051
  if (selected) {
1052
  document.getSelection().removeAllRanges();
flowplayer/modules/hls-live-check.module.js CHANGED
@@ -4,7 +4,7 @@ If there is an error in live stream, it shows a special message and reload the s
4
 
5
  flowplayer( function(api,root) {
6
  var
7
- initialDelay = 30,
8
  continueDelay = 10,
9
  useDelay = initialDelay,
10
  retryLabel = fv_flowplayer_translations.live_stream_retry,
4
 
5
  flowplayer( function(api,root) {
6
  var
7
+ initialDelay = api.conf.live_stream_reload ? api.conf.live_stream_reload : 30,
8
  continueDelay = 10,
9
  useDelay = initialDelay,
10
  retryLabel = fv_flowplayer_translations.live_stream_retry,
flowplayer/modules/learndash.module.js CHANGED
@@ -11,6 +11,10 @@ flowplayer( function(api,root) {
11
  LearnDash_watchPlayers();
12
 
13
  api.on("finish", function(e,api,time) {
 
 
 
 
14
  // Enable "Mark Complete" button
15
  window.LearnDash_disable_assets(false);
16
  });
11
  LearnDash_watchPlayers();
12
 
13
  api.on("finish", function(e,api,time) {
14
+ if( typeof(api.video.click) == "string" ) {
15
+ return;
16
+ }
17
+
18
  // Enable "Mark Complete" button
19
  window.LearnDash_disable_assets(false);
20
  });
flowplayer/modules/mobile.module.js CHANGED
@@ -26,10 +26,10 @@ function fv_flowplayer_mobile_switch(id) {
26
  }
27
 
28
  if( typeof(fv_flowplayer_mobile_switch_array) != "undefined" ) {
29
- for( var i in fv_flowplayer_mobile_switch_array ) {
30
- if( !fv_flowplayer_mobile_switch_array.hasOwnProperty(i) ) continue;
31
 
32
- fv_flowplayer_mobile_switch( i );
33
  }
34
  }
35
 
26
  }
27
 
28
  if( typeof(fv_flowplayer_mobile_switch_array) != "undefined" ) {
29
+ for( var fv_flowplayer_mobile_switch_i in fv_flowplayer_mobile_switch_array ) {
30
+ if( !fv_flowplayer_mobile_switch_array.hasOwnProperty(fv_flowplayer_mobile_switch_i) ) continue;
31
 
32
+ fv_flowplayer_mobile_switch( fv_flowplayer_mobile_switch_i );
33
  }
34
  }
35
 
flowplayer/modules/multiple-playback.module.js CHANGED
@@ -66,6 +66,10 @@ flowplayer( function(api,root) {
66
  }
67
 
68
  }).on('resume', function() {
 
 
 
 
69
  // if we resume a video, we need to pause all the other ones, unless multiple playback is enabled
70
  if( !api.conf.multiple_playback ) {
71
  jQuery('.flowplayer[data-flowplayer-instance-id]').each( function() {
66
  }
67
 
68
  }).on('resume', function() {
69
+ if( !api.muted ) {
70
+ flowplayer.audible_instance = instance_id;
71
+ }
72
+
73
  // if we resume a video, we need to pause all the other ones, unless multiple playback is enabled
74
  if( !api.conf.multiple_playback ) {
75
  jQuery('.flowplayer[data-flowplayer-instance-id]').each( function() {
flowplayer/modules/old-browsers.module.js CHANGED
@@ -5,10 +5,10 @@ function fv_flowplayer_browser_ff_m4v( hash ) {
5
  }
6
 
7
  if( typeof(fv_flowplayer_browser_ff_m4v_array) != "undefined" ) {
8
- for( var i in fv_flowplayer_browser_ff_m4v_array ) {
9
- if( !fv_flowplayer_browser_ff_m4v_array.hasOwnProperty(i) ) continue;
10
 
11
- fv_flowplayer_browser_ff_m4v( i );
12
  }
13
  }
14
 
@@ -32,10 +32,10 @@ function fv_flowplayer_browser_chrome_fail( hash, sAttributes, sVideo, bAutobuff
32
  }
33
 
34
  if( typeof(fv_flowplayer_browser_chrome_fail_array) != "undefined" ) {
35
- for( var i in fv_flowplayer_browser_chrome_fail_array ) {
36
- if( !fv_flowplayer_browser_chrome_fail_array.hasOwnProperty(i) ) continue;
37
 
38
- fv_flowplayer_browser_chrome_fail( i, fv_flowplayer_browser_chrome_fail_array[i]['attrs'], fv_flowplayer_browser_chrome_fail_array[i]['mp4'], fv_flowplayer_browser_chrome_fail_array[i]['auto_buffer'] );
39
  }
40
  }
41
 
@@ -46,10 +46,10 @@ function fv_flowplayer_browser_ie( hash ) {
46
  }
47
 
48
  if( typeof(fv_flowplayer_browser_ie_array) != "undefined" ) {
49
- for( var i in fv_flowplayer_browser_ie_array ) {
50
- if( !fv_flowplayer_browser_ie_array.hasOwnProperty(i) ) continue;
51
 
52
- fv_flowplayer_browser_ie( i );
53
  }
54
  }
55
 
5
  }
6
 
7
  if( typeof(fv_flowplayer_browser_ff_m4v_array) != "undefined" ) {
8
+ for( var fv_flowplayer_browser_ff_m4v_i in fv_flowplayer_browser_ff_m4v_array ) {
9
+ if( !fv_flowplayer_browser_ff_m4v_array.hasOwnProperty(fv_flowplayer_browser_ff_m4v_i) ) continue;
10
 
11
+ fv_flowplayer_browser_ff_m4v( fv_flowplayer_browser_ff_m4v_i );
12
  }
13
  }
14
 
32
  }
33
 
34
  if( typeof(fv_flowplayer_browser_chrome_fail_array) != "undefined" ) {
35
+ for( var fv_flowplayer_browser_chrome_fail_i in fv_flowplayer_browser_chrome_fail_array ) {
36
+ if( !fv_flowplayer_browser_chrome_fail_array.hasOwnProperty(fv_flowplayer_browser_chrome_fail_i) ) continue;
37
 
38
+ fv_flowplayer_browser_chrome_fail( fv_flowplayer_browser_chrome_fail_i, fv_flowplayer_browser_chrome_fail_array[fv_flowplayer_browser_chrome_fail_i]['attrs'], fv_flowplayer_browser_chrome_fail_array[fv_flowplayer_browser_chrome_fail_i]['mp4'], fv_flowplayer_browser_chrome_fail_array[fv_flowplayer_browser_chrome_fail_i]['auto_buffer'] );
39
  }
40
  }
41
 
46
  }
47
 
48
  if( typeof(fv_flowplayer_browser_ie_array) != "undefined" ) {
49
+ for( var fv_flowplayer_browser_ie_i in fv_flowplayer_browser_ie_array ) {
50
+ if( !fv_flowplayer_browser_ie_array.hasOwnProperty(fv_flowplayer_browser_ie_i) ) continue;
51
 
52
+ fv_flowplayer_browser_ie( fv_flowplayer_browser_ie_i );
53
  }
54
  }
55
 
flowplayer/modules/playback-position.module.js CHANGED
@@ -19,9 +19,11 @@ if (!Date.now) {
19
  cookiePositionsKeyName = 'video_positions',
20
  cookiePlaylistsKeyName = 'player_playlist_item',
21
  tempPositionCookieKeyName = 'video_positions_tmp',
 
22
  tempPlaylistsCookieKeyName = 'player_playlist_item_tmp',
23
  tempSawCookieKeyName = 'video_saw_tmp',
24
  playPositions = [],
 
25
  playlistIndexes = [],
26
  sawVideo = [],
27
 
@@ -100,6 +102,7 @@ if (!Date.now) {
100
  if (api.video.sources) {
101
  var video_id = getVideoId(api.video);
102
  playPositions[video_id] = 0;
 
103
  sawVideo[video_id] = 1;
104
  }
105
  },
@@ -134,6 +137,7 @@ if (!Date.now) {
134
  postDataPositions.push({
135
  name: video_name,
136
  position: playPositions[video_name],
 
137
  saw: typeof(sawVideo[video_name]) != "undefined" ? sawVideo[video_name] : false
138
  });
139
  }
@@ -154,6 +158,7 @@ if (!Date.now) {
154
  if (!postDataPositions.length) {
155
  // no video positions? remove the temporary position cookie/localStorage data as well
156
  removeCookieKey(tempPositionCookieKeyName);
 
157
  removeCookieKey(tempSawCookieKeyName);
158
  return;
159
  }
@@ -165,6 +170,7 @@ if (!Date.now) {
165
  // which will get removed on next page load
166
  try {
167
  var temp_position_data = {},
 
168
  temp_saw_data = {},
169
  temp_playlist_data = {};
170
 
@@ -172,8 +178,11 @@ if (!Date.now) {
172
  for (var i in postDataPositions) {
173
  if( !postDataPositions.hasOwnProperty(i) ) continue;
174
 
175
- temp_position_data[postDataPositions[i].name] = postDataPositions[i].position;
176
- temp_saw_data[postDataPositions[i].name] = postDataPositions[i].saw;
 
 
 
177
  }
178
 
179
  // playlist and item
@@ -183,6 +192,7 @@ if (!Date.now) {
183
  }
184
 
185
  setCookieKey(tempPositionCookieKeyName, getSerialized(temp_position_data));
 
186
  setCookieKey(tempSawCookieKeyName, getSerialized(temp_saw_data));
187
  setCookieKey(tempPlaylistsCookieKeyName, getSerialized(temp_playlist_data));
188
  } catch (e) {
@@ -303,15 +313,13 @@ if (!Date.now) {
303
 
304
  var
305
  $root = jQuery(root),
306
- enabled = flowplayer.conf.video_position_save_enable && $root.data('save-position') != 'false' || $root.data('save-position'),
307
  progressEventsCount = 0,
308
  player_id = $root.data('player-id') ? $root.data('player-id') : false,
309
  item_changed = false,
310
 
311
- // used to seek into the desired last stored position when he video has started
312
- seekIntoPosition = function (e, api) {
313
- if( api.video && api.video.live ) return;
314
-
315
  var
316
  video_id = getVideoId(api.video),
317
  position = api.video.position;
@@ -347,7 +355,19 @@ if (!Date.now) {
347
  }
348
  }
349
 
350
- api.bind('progress', storeVideoPosition);
 
 
 
 
 
 
 
 
 
 
 
 
351
 
352
  // no temporary positions found, let's work with DB / cookies
353
  if (position) {
@@ -357,7 +377,7 @@ if (!Date.now) {
357
 
358
  // stores currently played/paused/stopped video position
359
  storeVideoPosition = function (e, api) {
360
- if (api.live) {
361
  return;
362
  }
363
 
@@ -368,6 +388,21 @@ if (!Date.now) {
368
 
369
  playPositions[video_id] = position;
370
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  if( api.conf.playlist.length > 0 ) {
372
  if( player_id ) playlistIndexes[ player_id ] = api.video.index; // player_id => playlist_item
373
  }
@@ -486,8 +521,14 @@ if (!Date.now) {
486
  }
487
 
488
  if ( item_index >= 0 && !item_changed ) {
489
- api.play(item_index);
 
 
 
490
  item_changed = true;
 
 
 
491
  }
492
 
493
  };
@@ -503,11 +544,15 @@ if (!Date.now) {
503
  // stop events
504
  api.bind('finish', removeVideoPosition);
505
 
506
- // seek into the last saved position, it also hooks the progress event
507
  // this used to run on ready event for !flowplayer.support.fvmobile,
508
  // but then we run into some reliability issue with HLS.js, so it's safer
509
  // to use progress
510
- api.one( 'progress', seekIntoPosition);
 
 
 
 
511
 
512
  api.bind('unload', function() {
513
  item_changed = false;
@@ -556,7 +601,8 @@ if (!Date.now) {
556
  // We do this as the position saving Ajax can no longer be synchronous and block the page reload
557
  // So sometimes it takes longer to progress than the page load
558
  if (flowplayer.conf.is_logged_in == '1') {
559
- var playlist = api.conf.playlist.length > 0 ? api.conf.playlist : [ api.conf.clip ],
 
560
  playlist_external = jQuery('[rel='+jQuery(root).attr('id')+']');
561
 
562
  for( var i in playlist ) {
@@ -564,10 +610,11 @@ if (!Date.now) {
564
 
565
  var video_id = getVideoId(playlist[i]),
566
  position = processTempData(tempPositionCookieKeyName,video_id),
 
567
  saw = processTempData(tempSawCookieKeyName,video_id);
568
 
569
  if( position ) {
570
- if( api.conf.playlist.length ) {
571
  // set the position
572
  api.conf.playlist[i].sources[0].position = position;
573
 
@@ -582,8 +629,19 @@ if (!Date.now) {
582
  }
583
  }
584
 
 
 
 
 
 
 
 
 
 
 
 
585
  if( saw ) {
586
- if( api.conf.playlist.length ) {
587
  api.conf.playlist[i].sources[0].saw = true;
588
  } else {
589
  api.conf.clip.sources[0].saw = true;
19
  cookiePositionsKeyName = 'video_positions',
20
  cookiePlaylistsKeyName = 'player_playlist_item',
21
  tempPositionCookieKeyName = 'video_positions_tmp',
22
+ tempTopPositionCookieKeyName = 'video_top_positions_tmp',
23
  tempPlaylistsCookieKeyName = 'player_playlist_item_tmp',
24
  tempSawCookieKeyName = 'video_saw_tmp',
25
  playPositions = [],
26
+ playTopPositions = [],
27
  playlistIndexes = [],
28
  sawVideo = [],
29
 
102
  if (api.video.sources) {
103
  var video_id = getVideoId(api.video);
104
  playPositions[video_id] = 0;
105
+ playTopPositions[video_id] = 0;
106
  sawVideo[video_id] = 1;
107
  }
108
  },
137
  postDataPositions.push({
138
  name: video_name,
139
  position: playPositions[video_name],
140
+ top_position: playTopPositions[video_name],
141
  saw: typeof(sawVideo[video_name]) != "undefined" ? sawVideo[video_name] : false
142
  });
143
  }
158
  if (!postDataPositions.length) {
159
  // no video positions? remove the temporary position cookie/localStorage data as well
160
  removeCookieKey(tempPositionCookieKeyName);
161
+ removeCookieKey(tempTopPositionCookieKeyName);
162
  removeCookieKey(tempSawCookieKeyName);
163
  return;
164
  }
170
  // which will get removed on next page load
171
  try {
172
  var temp_position_data = {},
173
+ temp_top_position_data = {},
174
  temp_saw_data = {},
175
  temp_playlist_data = {};
176
 
178
  for (var i in postDataPositions) {
179
  if( !postDataPositions.hasOwnProperty(i) ) continue;
180
 
181
+ var name = postDataPositions[i].name;
182
+
183
+ temp_position_data[name] = postDataPositions[i].position;
184
+ temp_top_position_data[name] = postDataPositions[i].top_position;
185
+ temp_saw_data[name] = postDataPositions[i].saw;
186
  }
187
 
188
  // playlist and item
192
  }
193
 
194
  setCookieKey(tempPositionCookieKeyName, getSerialized(temp_position_data));
195
+ setCookieKey(tempTopPositionCookieKeyName, getSerialized(temp_top_position_data));
196
  setCookieKey(tempSawCookieKeyName, getSerialized(temp_saw_data));
197
  setCookieKey(tempPlaylistsCookieKeyName, getSerialized(temp_playlist_data));
198
  } catch (e) {
313
 
314
  var
315
  $root = jQuery(root),
316
+ enabled = flowplayer.conf.video_position_save_enable && $root.data('save-position') != false || $root.data('save-position'),
317
  progressEventsCount = 0,
318
  player_id = $root.data('player-id') ? $root.data('player-id') : false,
319
  item_changed = false,
320
 
321
+ // get stored video position
322
+ getVideoPosition = function (api) {
 
 
323
  var
324
  video_id = getVideoId(api.video),
325
  position = api.video.position;
355
  }
356
  }
357
 
358
+ return position;
359
+ },
360
+
361
+ isSupported = function() {
362
+ return !( api.live || api.video && typeof(api.video.click) == "string" );
363
+ },
364
+
365
+ // used to seek into the desired last stored position when he video has started
366
+ seekIntoPosition = function (e, api) {
367
+ // do not restore position for live video or video ad
368
+ if( !isSupported() ) return;
369
+
370
+ var position = getVideoPosition(api);
371
 
372
  // no temporary positions found, let's work with DB / cookies
373
  if (position) {
377
 
378
  // stores currently played/paused/stopped video position
379
  storeVideoPosition = function (e, api) {
380
+ if ( !isSupported() ) {
381
  return;
382
  }
383
 
388
 
389
  playPositions[video_id] = position;
390
 
391
+ // initialize top position variable with the already stored top position
392
+ if ( typeof(playTopPositions[video_id]) == "undefined" ) {
393
+ var stored_top_position = 0;
394
+ if ( api.conf.playlist ) {
395
+ stored_top_position = api.conf.playlist[api.video.index] && api.conf.playlist[api.video.index].sources[0] && api.conf.playlist[api.video.index].sources[0].top_position ? api.conf.playlist[api.video.index].sources[0].top_position : 0;
396
+ } else {
397
+ stored_top_position = api.conf.clip.sources[0] && api.conf.clip.sources[0].top_position ? api.conf.clip.sources[0].top_position : 0;
398
+ }
399
+ playTopPositions[video_id] = stored_top_position;
400
+
401
+ // only store the top position if the new one is bigger
402
+ } else if( playTopPositions[video_id] < position) {
403
+ playTopPositions[video_id] = position
404
+ }
405
+
406
  if( api.conf.playlist.length > 0 ) {
407
  if( player_id ) playlistIndexes[ player_id ] = api.video.index; // player_id => playlist_item
408
  }
521
  }
522
 
523
  if ( item_index >= 0 && !item_changed ) {
524
+ if( api.video && api.video.type != 'video/youtube' ) {
525
+ api.play(item_index);
526
+ }
527
+
528
  item_changed = true;
529
+
530
+ // playlist-start-position.module.js should not interfere
531
+ $root.data('position_changed', 1);
532
  }
533
 
534
  };
544
  // stop events
545
  api.bind('finish', removeVideoPosition);
546
 
547
+ // seek into the last saved position
548
  // this used to run on ready event for !flowplayer.support.fvmobile,
549
  // but then we run into some reliability issue with HLS.js, so it's safer
550
  // to use progress
551
+ api.on( 'ready', function() {
552
+ api.one( 'progress', seekIntoPosition);
553
+ });
554
+
555
+ api.bind('progress', storeVideoPosition);
556
 
557
  api.bind('unload', function() {
558
  item_changed = false;
601
  // We do this as the position saving Ajax can no longer be synchronous and block the page reload
602
  // So sometimes it takes longer to progress than the page load
603
  if (flowplayer.conf.is_logged_in == '1') {
604
+ var is_playlist = api.conf.playlist.length > 0,
605
+ playlist = is_playlist ? api.conf.playlist : [ api.conf.clip ],
606
  playlist_external = jQuery('[rel='+jQuery(root).attr('id')+']');
607
 
608
  for( var i in playlist ) {
610
 
611
  var video_id = getVideoId(playlist[i]),
612
  position = processTempData(tempPositionCookieKeyName,video_id),
613
+ top_position = processTempData(tempTopPositionCookieKeyName,video_id),
614
  saw = processTempData(tempSawCookieKeyName,video_id);
615
 
616
  if( position ) {
617
+ if( is_playlist ) {
618
  // set the position
619
  api.conf.playlist[i].sources[0].position = position;
620
 
629
  }
630
  }
631
 
632
+ // Accept the new top position if there is none or if then new one is bigger
633
+ if( top_position ) {
634
+ if( !playlist[i].sources[0].top_position || playlist[i].sources[0].top_position < top_position ) {
635
+ if( is_playlist ) {
636
+ api.conf.playlist[i].sources[0].top_position = top_position;
637
+ } else {
638
+ api.conf.clip.sources[0].top_position = top_position;
639
+ }
640
+ }
641
+ }
642
+
643
  if( saw ) {
644
+ if( is_playlist ) {
645
  api.conf.playlist[i].sources[0].saw = true;
646
  } else {
647
  api.conf.clip.sources[0].saw = true;
flowplayer/modules/playlist-repeat.module.js CHANGED
@@ -2,8 +2,8 @@ flowplayer( function(api,root) {
2
  root = jQuery(root);
3
  var original_prev, original_next, random_seed;
4
 
5
- if( !root.data('button-no-picture') && !root.data('button-repeat') && !root.data('button-rewind') ) return;
6
-
7
  api.bind('ready', function(e,api) {
8
 
9
  // Backup original api.next() and api.prev()
@@ -12,7 +12,8 @@ flowplayer( function(api,root) {
12
  original_prev = api.prev;
13
  }
14
 
15
- if( !api.video.type.match(/^audio/) && root.data('button-no-picture') && root.find('.fv-fp-no-picture').length == 0 ) {
 
16
  var button_no_picture = jQuery('<span class="fv-fp-no-picture"><svg viewBox="0 0 90 80" width="18px" height="18px" class="fvp-icon fvp-nopicture"><use xlink:href="#fvp-nopicture"></use></svg></span>');
17
 
18
  button_no_picture.insertAfter( root.find('.fp-controls .fp-volume') ).on('click', function(e) {
2
  root = jQuery(root);
3
  var original_prev, original_next, random_seed;
4
 
5
+ if( !root.data('button-no_picture') && !root.data('button-repeat') && !root.data('button-rewind') ) return;
6
+
7
  api.bind('ready', function(e,api) {
8
 
9
  // Backup original api.next() and api.prev()
12
  original_prev = api.prev;
13
  }
14
 
15
+ if( !api.video.type.match(/^audio/) && root.data('button-no_picture') && root.find('.fv-fp-no-picture').length == 0 ) {
16
+
17
  var button_no_picture = jQuery('<span class="fv-fp-no-picture"><svg viewBox="0 0 90 80" width="18px" height="18px" class="fvp-icon fvp-nopicture"><use xlink:href="#fvp-nopicture"></use></svg></span>');
18
 
19
  button_no_picture.insertAfter( root.find('.fp-controls .fp-volume') ).on('click', function(e) {
flowplayer/modules/playlist-start-position.module.js CHANGED
@@ -9,7 +9,11 @@ flowplayer( function(api,root) {
9
  function start_position_changer() {
10
  if ($root.data('position_changed') !== 1 && api.conf.playlist.length) {
11
  start_index--; // the index should start from 0
12
- api.play(start_index);
 
 
 
 
13
  $root.data('position_changed', 1);
14
  }
15
  }
9
  function start_position_changer() {
10
  if ($root.data('position_changed') !== 1 && api.conf.playlist.length) {
11
  start_index--; // the index should start from 0
12
+ // Do not go to the playlist item if it's ad
13
+ // TODO: Have it pick the previous video
14
+ if( typeof(api.conf.playlist[start_index].click) == "undefined" ) {
15
+ api.play(start_index);
16
+ }
17
  $root.data('position_changed', 1);
18
  }
19
  }
flowplayer/modules/sticky.module.js CHANGED
@@ -4,8 +4,9 @@
4
  var $playerDiv = $root.find('.fp-player');
5
  var sticky = $root.data("fvsticky");
6
  var globalSticky = false;
7
- var videoRatio = $root.data("ratio"),
8
- is_sticky = false;
 
9
 
10
  if (typeof(videoRatio) == "undefined") {
11
  videoRatio = 0.5625;
@@ -28,20 +29,12 @@
28
  }
29
 
30
  function fv_player_sticky_video() {
31
- var change = false;
32
  var $window = jQuery(window),
33
  $flowplayerDiv = $root,
34
  top = $flowplayerDiv.offset().top,
35
  offset = Math.floor(top + ($flowplayerDiv.outerHeight() / 2));
36
-
37
- api.on('ready', function() {
38
- change = true;
39
- });
40
- api.on('progress', function() {
41
- change = true;
42
- });
43
  api.on('unload', function() {
44
- change = false;
45
  fv_player_sticky_class_remove();
46
  $root.removeClass("is-unSticky");
47
  });
@@ -49,7 +42,7 @@
49
  $window
50
  .on("resize", function() {
51
  if( !is_big_enough() ) {
52
- if( is_sticky ) {
53
  fv_player_sticky_class_remove();
54
  }
55
  return;
@@ -60,24 +53,24 @@
60
  })
61
  .on("scroll", function() {
62
  if( !is_big_enough() ) {
63
- if( is_sticky ) {
64
  fv_player_sticky_class_remove();
65
  }
66
  return;
67
  }
68
 
69
  top = $flowplayerDiv.offset().top;
70
- offset = Math.floor(top + ($flowplayerDiv.outerHeight() / 2));
71
- if ($window.scrollTop() > offset && change) {
 
 
72
  if (jQuery("div.flowplayer.is-unSticky").length > 0) {
73
- console.log('unSticky', jQuery("div.flowplayer.is-unSticky").length);
74
  return false;
75
  } else {
76
  fv_player_sticky_class_add();
77
  }
78
  } else {
79
  fv_player_sticky_class_remove();
80
- change = false;
81
  }
82
  });
83
  }
@@ -86,6 +79,7 @@
86
  if ($playerDiv.hasClass("is-sticky-" + stickyPlace)) {
87
  return;
88
  } else {
 
89
  $playerDiv.addClass("is-sticky-" + stickyPlace);
90
  if ($root.find("a.fp-sticky").length == 0){
91
  $root.find('div.fp-header').prepend('<a class="fp-sticky fp-icon"></a>');
@@ -94,34 +88,56 @@
94
  $playerDiv.css("height", stickyHeight);
95
  $playerDiv.css("max-height", stickyHeight);
96
 
97
- is_sticky = true;
98
  api.trigger( 'sticky', [ api ] );
99
  }
100
  $playerDiv.parent(".flowplayer").addClass("is-stickable");
101
  }
102
 
103
  function fv_player_sticky_class_remove() {
 
104
  $playerDiv.removeClass("is-sticky-" + stickyPlace);
105
  $playerDiv.css("width", "");
106
  $playerDiv.css("height", "");
107
  $playerDiv.css("max-height", "");
108
  $playerDiv.parent(".flowplayer").removeClass("is-stickable");
109
 
110
- if( is_sticky ) {
111
- is_sticky = false;
112
  api.trigger( 'sticky-exit', [ api ] );
113
  }
114
  }
115
 
116
  function is_big_enough() {
117
- return jQuery(window).innerWidth() >= 1020;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  }
119
  });
120
 
121
  jQuery(function($) {
122
  $(document).on('click', "a.fp-sticky", function() {
123
- $("div.flowplayer.is-stickable").addClass("is-unSticky");
124
- var $playerDiv = $("div.flowplayer.is-stickable").find('.fp-player');
 
 
 
 
 
125
  $playerDiv.removeClass("is-sticky-right-bottom");
126
  $playerDiv.removeClass("is-sticky-left-bottom");
127
  $playerDiv.removeClass("is-sticky-right-top");
@@ -130,8 +146,8 @@ jQuery(function($) {
130
  $playerDiv.css("height", "");
131
  $playerDiv.css("max-height", "");
132
 
133
- if( is_sticky ) {
134
- is_sticky = false;
135
  api.trigger( 'sticky-exit', [ api ] );
136
  }
137
  });
4
  var $playerDiv = $root.find('.fp-player');
5
  var sticky = $root.data("fvsticky");
6
  var globalSticky = false;
7
+ var videoRatio = $root.data("ratio");
8
+
9
+ api.is_sticky = false;
10
 
11
  if (typeof(videoRatio) == "undefined") {
12
  videoRatio = 0.5625;
29
  }
30
 
31
  function fv_player_sticky_video() {
 
32
  var $window = jQuery(window),
33
  $flowplayerDiv = $root,
34
  top = $flowplayerDiv.offset().top,
35
  offset = Math.floor(top + ($flowplayerDiv.outerHeight() / 2));
36
+
 
 
 
 
 
 
37
  api.on('unload', function() {
 
38
  fv_player_sticky_class_remove();
39
  $root.removeClass("is-unSticky");
40
  });
42
  $window
43
  .on("resize", function() {
44
  if( !is_big_enough() ) {
45
+ if( api.is_sticky ) {
46
  fv_player_sticky_class_remove();
47
  }
48
  return;
53
  })
54
  .on("scroll", function() {
55
  if( !is_big_enough() ) {
56
+ if( api.is_sticky ) {
57
  fv_player_sticky_class_remove();
58
  }
59
  return;
60
  }
61
 
62
  top = $flowplayerDiv.offset().top;
63
+ offset = Math.floor(top + ($flowplayerDiv.outerHeight() / 2));
64
+
65
+ // Is the player loading, or is it the audible player?
66
+ if ($window.scrollTop() > offset && ( api.loading || flowplayer.audible_instance == $root.data('flowplayer-instance-id') ) ) {
67
  if (jQuery("div.flowplayer.is-unSticky").length > 0) {
 
68
  return false;
69
  } else {
70
  fv_player_sticky_class_add();
71
  }
72
  } else {
73
  fv_player_sticky_class_remove();
 
74
  }
75
  });
76
  }
79
  if ($playerDiv.hasClass("is-sticky-" + stickyPlace)) {
80
  return;
81
  } else {
82
+ $playerDiv.addClass("is-sticky");
83
  $playerDiv.addClass("is-sticky-" + stickyPlace);
84
  if ($root.find("a.fp-sticky").length == 0){
85
  $root.find('div.fp-header').prepend('<a class="fp-sticky fp-icon"></a>');
88
  $playerDiv.css("height", stickyHeight);
89
  $playerDiv.css("max-height", stickyHeight);
90
 
91
+ api.is_sticky = true;
92
  api.trigger( 'sticky', [ api ] );
93
  }
94
  $playerDiv.parent(".flowplayer").addClass("is-stickable");
95
  }
96
 
97
  function fv_player_sticky_class_remove() {
98
+ $playerDiv.removeClass("is-sticky");
99
  $playerDiv.removeClass("is-sticky-" + stickyPlace);
100
  $playerDiv.css("width", "");
101
  $playerDiv.css("height", "");
102
  $playerDiv.css("max-height", "");
103
  $playerDiv.parent(".flowplayer").removeClass("is-stickable");
104
 
105
+ if( api.is_sticky ) {
106
+ api.is_sticky = false;
107
  api.trigger( 'sticky-exit', [ api ] );
108
  }
109
  }
110
 
111
  function is_big_enough() {
112
+ return jQuery(window).innerWidth() >= fv_flowplayer_conf.sticky_min_width;
113
+ }
114
+
115
+ api.sticky = function( flag, remember ) {
116
+ if( typeof(flag) == "undefined" ) {
117
+ flag = !api.is_sticky;
118
+ }
119
+
120
+ if( remember ) {
121
+ $root.toggleClass("is-unSticky", !flag );
122
+ }
123
+
124
+ if( flag ) {
125
+ fv_player_sticky_class_add();
126
+ } else {
127
+ fv_player_sticky_class_remove();
128
+ }
129
  }
130
  });
131
 
132
  jQuery(function($) {
133
  $(document).on('click', "a.fp-sticky", function() {
134
+ var root = $("div.flowplayer.is-stickable"),
135
+ api = root.data('flowplayer');
136
+
137
+ root.addClass("is-unSticky");
138
+
139
+ var $playerDiv = root.find('.fp-player');
140
+ $playerDiv.removeClass("is-sticky");
141
  $playerDiv.removeClass("is-sticky-right-bottom");
142
  $playerDiv.removeClass("is-sticky-left-bottom");
143
  $playerDiv.removeClass("is-sticky-right-top");
146
  $playerDiv.css("height", "");
147
  $playerDiv.css("max-height", "");
148
 
149
+ if( api.is_sticky ) {
150
+ api.is_sticky = false;
151
  api.trigger( 'sticky-exit', [ api ] );
152
  }
153
  });
flowplayer/modules/volume.module.js CHANGED
@@ -10,9 +10,14 @@
10
  flowplayer(function(api, root) {
11
  root = jQuery(root);
12
  var bean = flowplayer.bean;
13
- var restore = flowplayer.conf.default_volume;
14
 
15
  // Restore volume on click on the speaker icon
 
 
 
 
 
 
16
  root.on('mousedown touchstart','.fp-volumebtn', function(e) {
17
  var volumebtn = jQuery(this);
18
 
10
  flowplayer(function(api, root) {
11
  root = jQuery(root);
12
  var bean = flowplayer.bean;
 
13
 
14
  // Restore volume on click on the speaker icon
15
+ var restore = flowplayer.conf.default_volume;
16
+ // Watch out, the website default might be to use a zero volume!
17
+ if( restore == 0 ) {
18
+ restore = "0.5";
19
+ }
20
+
21
  root.on('mousedown touchstart','.fp-volumebtn', function(e) {
22
  var volumebtn = jQuery(this);
23
 
includes/mailchimp-api/composer.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "name": "drewm/mailchimp-api",
3
- "description": "Super-simple, minimum abstraction MailChimp API v3 wrapper",
4
- "license": "MIT",
5
- "require": {
6
- "php": ">=5.3",
7
- "ext-curl": "*"
8
- },
9
- "require-dev": {
10
- "phpunit/phpunit": "4.0.*",
11
- "vlucas/phpdotenv": "^2.0"
12
- },
13
- "autoload": {
14
- "psr-4": {
15
- "DrewM\\MailChimp\\": "src"
16
- }
17
- },
18
- "homepage": "https://github.com/drewm/mailchimp-api",
19
- "authors": [
20
- {
21
- "name": "Drew McLellan",
22
- "email": "drew.mclellan@gmail.com",
23
- "homepage": "http://allinthehead.com/"
24
-
25
- }
26
- ]
27
-
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/admin-convertor.js CHANGED
@@ -8,13 +8,29 @@ $.fn.Progressor = function(args) {
8
  $.ajax({
9
  url: opts.url,
10
  cache: false,
11
- data: ({ action: opts.action, offset: offset, limit: opts.limit, _ajax_nonce: opts.nonce, offset2: $('[name=offset]').val(), verbose: $('[name=verbose]').is(':checked')
 
 
 
 
 
 
 
12
  }),
13
  type: 'POST',
14
  error: showAlert ,
15
  success: function(data) {
16
- var response = JSON.parse(data),
17
- percent = response.percent_done,
 
 
 
 
 
 
 
 
 
18
  table_rows = response.table_rows,
19
  left = response.left,
20
  convert_error = false;
@@ -23,10 +39,8 @@ $.fn.Progressor = function(args) {
23
  convert_error = true;
24
  }
25
 
26
- console.log('Error', convert_error);
27
-
28
  $('#progress').css('width', percent+'%');
29
-
30
  $("#output").append(table_rows);
31
 
32
  if (left > 0) {
@@ -35,7 +49,7 @@ $.fn.Progressor = function(args) {
35
  setTimeout(timer, 0);
36
  } else {
37
  // Finished
38
-
39
  $('#progress').css('width', '100%');
40
 
41
  $('#loading').hide();
@@ -44,7 +58,7 @@ $.fn.Progressor = function(args) {
44
 
45
  if( !running ) {
46
  $(opts.start).val(original);
47
-
48
  if( convert_error ) {
49
  $('#export').show();
50
  }
@@ -68,9 +82,10 @@ $.fn.Progressor = function(args) {
68
  var wrapper = this;
69
  var messages = $('#messages');
70
  var original = $(opts.start).val();
 
71
 
72
  $(opts.start).click(function() {
73
- var button = this;
74
 
75
  if (running) {
76
  // Cancel
@@ -82,6 +97,8 @@ $.fn.Progressor = function(args) {
82
  }
83
  }
84
  else {
 
 
85
  offset = 0;
86
  running = true;
87
 
8
  $.ajax({
9
  url: opts.url,
10
  cache: false,
11
+ data: ({
12
+ action: opts.action,
13
+ offset: offset,
14
+ limit: opts.limit,
15
+ _ajax_nonce: opts.nonce,
16
+ offset2: $('[name=offset]').val(),
17
+ verbose: $('[name=verbose]').is(':checked'),
18
+ 'make-changes': jQuery('#make-changes').prop('checked')
19
  }),
20
  type: 'POST',
21
  error: showAlert ,
22
  success: function(data) {
23
+ try {
24
+ var response = JSON.parse(data);
25
+ } catch(e) {
26
+ alert('Error in conversion Ajax, please check the PHP error log');
27
+ $(button).val('Start');
28
+ $('#loading').hide();
29
+ running = false;
30
+ return;
31
+ }
32
+
33
+ var percent = response.percent_done,
34
  table_rows = response.table_rows,
35
  left = response.left,
36
  convert_error = false;
39
  convert_error = true;
40
  }
41
 
 
 
42
  $('#progress').css('width', percent+'%');
43
+
44
  $("#output").append(table_rows);
45
 
46
  if (left > 0) {
49
  setTimeout(timer, 0);
50
  } else {
51
  // Finished
52
+
53
  $('#progress').css('width', '100%');
54
 
55
  $('#loading').hide();
58
 
59
  if( !running ) {
60
  $(opts.start).val(original);
61
+
62
  if( convert_error ) {
63
  $('#export').show();
64
  }
82
  var wrapper = this;
83
  var messages = $('#messages');
84
  var original = $(opts.start).val();
85
+ var button;
86
 
87
  $(opts.start).click(function() {
88
+ button = this;
89
 
90
  if (running) {
91
  // Cancel
97
  }
98
  }
99
  else {
100
+ $("#output").html('');
101
+
102
  offset = 0;
103
  running = true;
104
 
js/editor-screenshots.js CHANGED
@@ -7,7 +7,7 @@
7
  flowplayer( function(api,root) {
8
  root = jQuery(root);
9
  var button = jQuery('<input type="button" value="Screenshot" class="button" id="fv-splash-screen-button" />'),
10
- spinner =jQuery('<div class="fv-player-shortcode-editor-small-spinner">&nbsp;</div>'),
11
  message = jQuery('.fv-messages'),
12
  title ='';
13
 
@@ -15,8 +15,9 @@
15
  var seek_recovery = false;
16
 
17
  function takeScreenshot() {
18
- var video = root.find('video').get(0);
19
- var canvas = document.createElement("canvas");
 
20
  canvas.width = video.videoWidth * 1;
21
  canvas.height = video.videoHeight * 1;
22
  canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
@@ -30,16 +31,17 @@
30
  button.on('click', function(){
31
  try {
32
  button.prop("disabled",true);
33
-
34
- var screenshot = takeScreenshot();
35
- var item = jQuery('.fv-player-playlist-item[data-index="'+index+'"]');
 
36
  spinner.insertAfter( item.find('#fv_wp_flowplayer_field_splash') );
37
-
38
  // Check title
39
  if(item.find('#fv_wp_flowplayer_field_caption').val()){
40
- title = item.find('#fv_wp_flowplayer_field_caption').val()
41
- }else{
42
- title = item.find('#fv_wp_flowplayer_field_src').val()
43
  }
44
  var data = {
45
  'action': 'fv_player_splashcreen_action',
@@ -118,48 +120,48 @@
118
  }
119
  }
120
  });
121
-
122
  // Resume video after setting crossOrigin
123
  api.on('resume progress', function(e) {
124
  if( seek_recovery && api.video.seekable ) {
125
  api.seek(seek_recovery, function() {
126
  seek_recovery = false;
127
-
128
  // try to take the screenshot again
129
  button.click();
130
  });
131
  }
132
  });
133
-
134
  // Show error if video fails after setting crossOrigin
135
  api.on('error', function(e, api, err) {
136
  if( seek_recovery ) {
137
  // prevent FV Player Pro from trying to recover
138
  api.fv_retry_count = 100;
139
-
140
  console.log('FV Player Editor Screenshots: Video won\'t play with crossOrigin="anonymous"');
141
-
142
  show_error();
143
  }
144
  });
145
-
146
  function reload_video() {
147
  seek_recovery = api.video.time;
148
 
149
  var index = typeof(api.video.index) != "undefined" ? api.video.index : 0;
150
-
151
  api.error = api.loading = false;
152
  jQuery(root).find('.fp-message').remove();
153
  jQuery(root).removeClass("is-error").addClass("is-mouseover");
154
-
155
  if( api.conf.playlist.length ) {
156
  api.setPlaylist(api.conf.playlist).play(index);
157
  } else {
158
  api.load(api.conf.clip);
159
  }
160
-
161
  }
162
-
163
  function show_error() {
164
  spinner.remove();
165
  button.prop("disabled",false);
@@ -172,14 +174,14 @@
172
  // Remove button, spinner, message
173
  jQuery(document).on('fv_flowplayer_player_editor_reset', function() {
174
  jQuery('#fv-splash-screen-button').remove();
175
- jQuery('.fv-player-shortcode-editor-small-spinner').remove();
176
  jQuery('.fv-messages').empty();
177
  index = 0;
178
  });
179
 
180
  jQuery(document).on('fvp-preview-complete', function() {
181
  jQuery('#fv-splash-screen-button').remove();
182
- jQuery('.fv-player-shortcode-editor-small-spinner').remove();
183
  jQuery('.fv-messages').empty();
184
  });
185
 
7
  flowplayer( function(api,root) {
8
  root = jQuery(root);
9
  var button = jQuery('<input type="button" value="Screenshot" class="button" id="fv-splash-screen-button" />'),
10
+ spinner =jQuery('<div id="fv-editor-screenshot-spinner" class="fv-player-shortcode-editor-small-spinner">&nbsp;</div>'),
11
  message = jQuery('.fv-messages'),
12
  title ='';
13
 
15
  var seek_recovery = false;
16
 
17
  function takeScreenshot() {
18
+ var video = root.find('video').get(0),
19
+ canvas = document.createElement("canvas");
20
+
21
  canvas.width = video.videoWidth * 1;
22
  canvas.height = video.videoHeight * 1;
23
  canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
31
  button.on('click', function(){
32
  try {
33
  button.prop("disabled",true);
34
+
35
+ var screenshot = takeScreenshot(),
36
+ item = jQuery('.fv-player-playlist-item[data-index="'+index+'"]');
37
+
38
  spinner.insertAfter( item.find('#fv_wp_flowplayer_field_splash') );
39
+
40
  // Check title
41
  if(item.find('#fv_wp_flowplayer_field_caption').val()){
42
+ title = item.find('#fv_wp_flowplayer_field_caption').val();
43
+ } else {
44
+ title = item.find('#fv_wp_flowplayer_field_src').val();
45
  }
46
  var data = {
47
  'action': 'fv_player_splashcreen_action',
120
  }
121
  }
122
  });
123
+
124
  // Resume video after setting crossOrigin
125
  api.on('resume progress', function(e) {
126
  if( seek_recovery && api.video.seekable ) {
127
  api.seek(seek_recovery, function() {
128
  seek_recovery = false;
129
+
130
  // try to take the screenshot again
131
  button.click();
132
  });
133
  }
134
  });
135
+
136
  // Show error if video fails after setting crossOrigin
137
  api.on('error', function(e, api, err) {
138
  if( seek_recovery ) {
139
  // prevent FV Player Pro from trying to recover
140
  api.fv_retry_count = 100;
141
+
142
  console.log('FV Player Editor Screenshots: Video won\'t play with crossOrigin="anonymous"');
143
+
144
  show_error();
145
  }
146
  });
147
+
148
  function reload_video() {
149
  seek_recovery = api.video.time;
150
 
151
  var index = typeof(api.video.index) != "undefined" ? api.video.index : 0;
152
+
153
  api.error = api.loading = false;
154
  jQuery(root).find('.fp-message').remove();
155
  jQuery(root).removeClass("is-error").addClass("is-mouseover");
156
+
157
  if( api.conf.playlist.length ) {
158
  api.setPlaylist(api.conf.playlist).play(index);
159
  } else {
160
  api.load(api.conf.clip);
161
  }
162
+
163
  }
164
+
165
  function show_error() {
166
  spinner.remove();
167
  button.prop("disabled",false);
174
  // Remove button, spinner, message
175
  jQuery(document).on('fv_flowplayer_player_editor_reset', function() {
176
  jQuery('#fv-splash-screen-button').remove();
177
+ jQuery('#fv-editor-screenshot-spinner').remove();
178
  jQuery('.fv-messages').empty();
179
  index = 0;
180
  });
181
 
182
  jQuery(document).on('fvp-preview-complete', function() {
183
  jQuery('#fv-splash-screen-button').remove();
184
+ jQuery('#fv-editor-screenshot-spinner').remove();
185
  jQuery('.fv-messages').empty();
186
  });
187
 
js/media-library-browser-base.js CHANGED
@@ -166,7 +166,7 @@ function fv_flowplayer_browser_browse(data, options) {
166
  icon = '';
167
 
168
  if( f.splash ) {
169
- icon = '<img src="' + f.splash + '" draggable="false" class="icon thumb" title="' + name + '" />';
170
  } else {
171
  var fileType = name.split('.');
172
  if( fileType.length > 1 ) {
@@ -784,7 +784,7 @@ jQuery( function($) {
784
  var
785
  isPicture = $filenameDiv.data('link').match(/\.(jpg|jpeg|png|gif)$/),
786
  splashValue = getFileSplashImage( locateSplashFileObjectForMediaFileHref( $filenameDiv.data('link') ) ),
787
- splash = (isPicture ? $e.find('.icon').get(0).outerHTML : '<img src="' + splashValue + '" draggable="false" class="icon thumb" />');
788
 
789
  // if we didn't find a splash image for a media file,
790
  // use its icon
166
  icon = '';
167
 
168
  if( f.splash ) {
169
+ icon = '<img src="' + f.splash + '" draggable="false" class="icon thumb" title="' + name + '" loading="lazy" />';
170
  } else {
171
  var fileType = name.split('.');
172
  if( fileType.length > 1 ) {
784
  var
785
  isPicture = $filenameDiv.data('link').match(/\.(jpg|jpeg|png|gif)$/),
786
  splashValue = getFileSplashImage( locateSplashFileObjectForMediaFileHref( $filenameDiv.data('link') ) ),
787
+ splash = (isPicture ? $e.find('.icon').get(0).outerHTML : '<img src="' + splashValue + '" draggable="false" class="icon thumb" loading="lazy" />');
788
 
789
  // if we didn't find a splash image for a media file,
790
  // use its icon
js/shortcode-editor.js CHANGED
@@ -7,6 +7,7 @@ var fv_player_editor_matcher = {
7
  matcher: /\.(mp4|webm|m3u8)$/i,
8
  // AJAX will return these fields which can be auto-updated via JS
9
  update_fields: ['duration', 'last_video_meta_check'],
 
10
  }
11
  };
12
 
@@ -30,6 +31,8 @@ jQuery(function() {
30
  ajax_save_previous = false,
31
 
32
  current_player_db_id = -1,
 
 
33
  current_video_to_edit = -1,
34
 
35
  // stores the button which was clicked to open the editor
@@ -65,8 +68,7 @@ jQuery(function() {
65
  editing_video_details = false,
66
 
67
  // which playlist item we're currently editing, set to -1 if we're showing playlist view
68
- // this is used when loading data from DB to avoid previewing an empty video that's in editor by default
69
- item_index = -1,
70
 
71
  // are we currently saving data?
72
  is_saving = false,
@@ -113,7 +115,7 @@ jQuery(function() {
113
  errors = {};
114
 
115
 
116
- /*
117
  * A shorthand to save you from all the "fv_wp_flowplayer_field_"
118
  * when selecting fields
119
  *
@@ -121,7 +123,8 @@ jQuery(function() {
121
  * you "fv_wp_flowplayer_field_src"
122
  * @param {object|string} where Lets you narrow down the element wher you
123
  * want to locate he field. You can use a jQuery
124
- * element or a string selector for jQuery
 
125
  *
126
  * @return {object} The field element
127
  */
@@ -129,7 +132,11 @@ jQuery(function() {
129
  var element = false,
130
  selector = '.' + fv_wp_flowplayer_map_names_to_editor_fields(key) + ', [name=' + fv_wp_flowplayer_map_names_to_editor_fields(key) + ']';
131
 
132
- if( where && typeof(where) == "object" ) {
 
 
 
 
133
  element = where.find(selector);
134
  } else if( where && typeof(where) == "string" ) {
135
  element = $el_editor.find(where).find(selector);
@@ -144,7 +151,7 @@ jQuery(function() {
144
  return element;
145
  }
146
 
147
- /*
148
  * Gives you "src" out of "fv_wp_flowplayer_field_src"
149
  *
150
  * @param {string} name The field name
@@ -158,7 +165,7 @@ jQuery(function() {
158
  return name;
159
  }
160
 
161
- /*
162
  * Gives you the desired tab with video information
163
  *
164
  * @param {int|string} index Number, or first, or last
@@ -180,7 +187,7 @@ jQuery(function() {
180
  return $el_editor.find(selector);
181
  }
182
 
183
- /*
184
  * Gives you all desired tabs of a certain kind
185
  *
186
  * @return {object} The tab elements
@@ -280,10 +287,7 @@ jQuery(function() {
280
  cookie: encodeURIComponent(document.cookie),
281
  }, function(json_export_data) {
282
  var overlay = overlay_show('export');
283
-
284
  overlay.find('textarea').val( $('<div/>').text(json_export_data).html() );
285
-
286
- jQuery('[name=fv_player_copy_to_clipboard]').select();
287
  }).fail(function() {
288
  overlay_show('message', 'An unexpected error has occurred. Please try again.');
289
  });
@@ -402,11 +406,13 @@ jQuery(function() {
402
  });
403
  } else {
404
  $spinner.remove();
405
- $element.html('Error');
 
406
  }
407
  }).fail(function() {
408
- $spinner
409
- $element.html('Error');
 
410
  });
411
 
412
  return false;
@@ -770,20 +776,8 @@ jQuery(function() {
770
  // show error overlay if we have errors
771
  var err = fv_player_editor.has_errors();
772
  if ( err ) {
773
- $el_save_error_p
774
- .data( 'old_txt', $el_save_error.text() )
775
- .text( err );
776
- $el_save_error.show();
777
-
778
  return;
779
- } else {
780
- // revert error text and hide error overlay if we have no errors to show
781
- if ( $el_save_error_p.data( 'old_txt ') ) {
782
- $el_save_error_p
783
- .text( $el_save_error_p.data( 'old_txt ') )
784
- .removeData( 'old_txt' );
785
- $el_save_error.hide();
786
- }
787
  }
788
 
789
  is_saving = true;
@@ -791,7 +785,7 @@ jQuery(function() {
791
 
792
  el_spinner.show();
793
 
794
- $('.fv-player-save-error').hide();
795
 
796
  debug_log('Running fv_player_db_save Ajax.');
797
 
@@ -799,12 +793,31 @@ jQuery(function() {
799
  action: 'fv_player_db_save',
800
  data: JSON.stringify(ajax_save_this_please),
801
  nonce: fv_player_editor_conf.preview_nonce,
802
- }, function(player) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
803
  try {
804
- $(player.videos).each( function(k,v) {
805
  var item = $('.fv-player-playlist-item').eq(k);
806
  if( !item.data('id_video') ) {
807
- item.attr('data-id_video',v);
 
 
 
 
 
808
  }
809
  });
810
 
@@ -815,9 +828,9 @@ jQuery(function() {
815
  next = false;
816
  } else {
817
  is_saving = false;
818
-
819
  insert_button_toggle_disabled(false);
820
-
821
  el_spinner.hide();
822
 
823
  $el_save_complete.show().delay( 2500 ).fadeOut(400);
@@ -830,9 +843,9 @@ jQuery(function() {
830
  }
831
  overlay_close_waiting_for_save = false;
832
  $.fn.fv_player_box.close();
833
- } else if ( player.html ) {
834
  // auto-refresh preview
835
- el_preview_target.html( player.html )
836
 
837
  $doc.trigger('fvp-preview-complete');
838
  }
@@ -841,8 +854,8 @@ jQuery(function() {
841
  // add all the data and inputs to page that we need for an existing player
842
  if ( is_unsaved ) {
843
  fv_player_editor.copy_player_button_toggle(false);
844
- init_saved_player_fields( player.id );
845
- current_player_db_id = player.id;
846
  is_unsaved = false;
847
  //is_draft_changed = false;
848
  loading = false;
@@ -854,7 +867,7 @@ jQuery(function() {
854
  }
855
 
856
  }, 'json' ).fail( function() {
857
- $('.fv-player-save-error').show();
858
 
859
  el_spinner.hide();
860
 
@@ -1426,7 +1439,7 @@ jQuery(function() {
1426
 
1427
 
1428
 
1429
- /*
1430
  * Initializes shortcode, removes playlist items, hides elements, figures out
1431
  * which actual field is edited - post editor, widget, etc.
1432
  */
@@ -1521,8 +1534,7 @@ jQuery(function() {
1521
  jQuery('#fv-player-shortcode-editor a[data-tab=fv-player-tab-video-files]').trigger('click');
1522
  jQuery('.nav-tab').show;
1523
 
1524
- current_player_db_id = -1;
1525
- item_index = 0;
1526
 
1527
  editing_video_details = true;
1528
  $el_editor.attr('class','is-singular is-singular-active');
@@ -1550,7 +1562,7 @@ jQuery(function() {
1550
  $doc.trigger('fv-player-editor-init');
1551
  }
1552
 
1553
- /*
1554
  * Checks all the input fields and created the JavaScript object.
1555
  * Works when saving and also previewing.
1556
  */
@@ -1840,7 +1852,7 @@ jQuery(function() {
1840
  }
1841
  }
1842
 
1843
- /*
1844
  * Closing the editor
1845
  * * updates the wp-admin -> FV Player screen
1846
  * * sets data for WordPress Heartbeat to unlock the player
@@ -1915,7 +1927,7 @@ jQuery(function() {
1915
  }
1916
 
1917
 
1918
- /*
1919
  * removes previous values from editor
1920
  * fills new values from shortcode
1921
  *
@@ -2154,9 +2166,11 @@ jQuery(function() {
2154
  debug_log('Finished fv_player_db_load Ajax.',response);
2155
 
2156
  if (response) {
2157
- if( typeof(response) != "object" ) {
2158
- overlay_show('message', 'Error: '+response);
2159
-
 
 
2160
  // The editor failed to load, it's not locked
2161
  edit_lock_removal[current_player_db_id] = 1;
2162
  return;
@@ -2172,6 +2186,8 @@ jQuery(function() {
2172
 
2173
  set_embeds(response['embeds']);
2174
 
 
 
2175
  // fire the player load event to cater for any plugins listening
2176
  var $doc = jQuery(document);
2177
  $doc.trigger('fv_flowplayer_player_meta_load', [response]);
@@ -2304,7 +2320,14 @@ jQuery(function() {
2304
  for (var i in video_meta) {
2305
  // video duration hidden input
2306
  if (['duration', 'last_video_meta_check', 'auto_splash', 'auto_caption'].indexOf(video_meta[i].meta_key) > -1) {
2307
- $video_data_tab.find('#fv_wp_flowplayer_field_src').after('<input type="hidden" name="fv_wp_flowplayer_field_' + video_meta[i].meta_key + '" id="fv_wp_flowplayer_field_' + video_meta[i].meta_key + '" value="' + video_meta[i].meta_value + '" data-id="' + video_meta[i].id + '" />');
 
 
 
 
 
 
 
2308
  } else {
2309
  // predefined meta input with field already existing in the dialog
2310
  set_player_field(video_meta[i].meta_key, video_meta[i].meta_value, video_meta[i].id, video_meta[i].id_video);
@@ -2432,7 +2455,7 @@ jQuery(function() {
2432
  fv_wp_flowplayer_shortcode_parse_arg( shortcode, aSubtitlesLangs[i], false, fv_wp_flowplayer_subtitle_parse_arg );
2433
  }
2434
  if(!aSubtitlesLangs){ // move
2435
- subtitle_language_add(false, false );
2436
  }
2437
 
2438
  var smobile = fv_wp_flowplayer_shortcode_parse_arg( shortcode, 'mobile' );
@@ -2475,7 +2498,7 @@ jQuery(function() {
2475
 
2476
  if( srcurl != null && srcurl[1] != null ) {
2477
  get_field('src').val(srcurl[1]);
2478
- playlist_row.find('.fvp_item_video-filename').html( srcurl[1] );
2479
  }
2480
 
2481
  get_field('width').val(iwidth[1] || '');
@@ -2512,7 +2535,12 @@ jQuery(function() {
2512
 
2513
  if( ssplash != null && ssplash[1] != null ) {
2514
  get_field("splash").val(ssplash[1]);
2515
- playlist_row.find('.fvp_item_splash').html( '<img width="120" src="'+ssplash[1]+'" />' );
 
 
 
 
 
2516
  }
2517
 
2518
  var aSubtitles = false;
@@ -2622,7 +2650,7 @@ jQuery(function() {
2622
 
2623
  var caption = aCaptions.shift();
2624
  get_field("caption").val( caption );
2625
- playlist_row.find('.fvp_item_caption div').html( caption );
2626
  }
2627
 
2628
  var aSplashText = false;
@@ -2713,8 +2741,8 @@ jQuery(function() {
2713
  }
2714
  }
2715
 
2716
- /*
2717
- * Calculate FV Player editor popup (Colorbox) size
2718
  */
2719
  function editor_resize() {
2720
  setTimeout(function(){
@@ -2736,7 +2764,7 @@ jQuery(function() {
2736
  },0);
2737
  }
2738
 
2739
- /*
2740
  * Saving the data
2741
  */
2742
  function editor_submit() {
@@ -2817,12 +2845,22 @@ jQuery(function() {
2817
  data: JSON.stringify(ajax_data),
2818
  nonce: fv_player_editor_conf.preview_nonce
2819
  }, function(response) {
 
 
 
 
 
 
 
 
 
 
2820
  // player saved, reset draft status
2821
  is_unsaved = false;
2822
  //is_draft_changed = false;
2823
 
2824
  var player = JSON.parse(response);
2825
- current_player_db_id = parseInt(player.id);
2826
  if( current_player_db_id > 0 ) {
2827
  var
2828
  has_store_shortcode_args = false,
@@ -2937,7 +2975,7 @@ jQuery(function() {
2937
  }
2938
  }
2939
 
2940
- /*
2941
  * Sends new shortcode to editor
2942
  */
2943
  function insert_shortcode( shortcode ) {
@@ -3104,7 +3142,7 @@ jQuery(function() {
3104
 
3105
  if (typeof sSubtitles === 'object' && sSubtitles.length && sSubtitles[0].lang) {
3106
  for (var i in sSubtitles) {
3107
- subtitle_language_add(sSubtitles[i].file, sSubtitles[i].lang, newIndex, sSubtitles[i].id);
3108
  }
3109
  }
3110
 
@@ -3166,6 +3204,11 @@ jQuery(function() {
3166
  get_tabs('video-files').hide();
3167
  var video_tab = get_tab(new_index,'video-files').show();
3168
 
 
 
 
 
 
3169
  get_tabs('subtitles').hide();
3170
  get_tab(new_index,'subtitles').show();
3171
 
@@ -3192,9 +3235,11 @@ jQuery(function() {
3192
  $('.fv_wp_flowplayer_field_subtitles_lang, .subtitle_language_add_link').attr('style',false);
3193
 
3194
  tabs_refresh();
 
 
3195
  }
3196
 
3197
- /*
3198
  * Recalculate the data-index values for playlist items
3199
  */
3200
  function playlist_index() {
@@ -3219,6 +3264,8 @@ jQuery(function() {
3219
  */
3220
  function playlist_show() {
3221
  item_index = -1;
 
 
3222
 
3223
  editing_video_details = false;
3224
  $el_editor.attr('class','is-playlist-active');
@@ -3243,19 +3290,23 @@ jQuery(function() {
3243
 
3244
  var playlist_row = jQuery('.fv-player-tab-playlist table tbody tr').eq( current.data('index') );
3245
 
3246
- var video_preview = get_field("splash",current).val();
3247
- playlist_row.find('.fvp_item_video-thumbnail').html( video_preview.length ? '<img src="' + video_preview + '" />':'');
 
 
 
 
3248
 
3249
  var video_name = decodeURIComponent(currentUrl).split("/").pop();
3250
  video_name = video_name.replace(/\+/g,' ');
3251
  video_name = video_name.replace(/watch\?v=/,'YouTube: ');
3252
 
3253
- playlist_row.find('.fvp_item_video-filename').html( video_name );
3254
 
3255
  var playlist_row_div = playlist_row.find('.fvp_item_caption div');
3256
  // do not put in caption if it's loading
3257
  if (!playlist_row_div.hasClass('fv-player-shortcode-editor-small-spinner')) {
3258
- playlist_row_div.html( get_field("caption",current).val() );
3259
  }
3260
  });
3261
 
@@ -3274,6 +3325,8 @@ jQuery(function() {
3274
  jQuery('.fv-player-tab-playlist').show();
3275
  editor_resize();
3276
  tabs_refresh();
 
 
3277
 
3278
  return false;
3279
  }
@@ -3291,6 +3344,13 @@ jQuery(function() {
3291
  height: height
3292
  };
3293
  }
 
 
 
 
 
 
 
3294
 
3295
  function set_post_editor_content( html ) {
3296
  if ( editor_button_clicked.className.indexOf('fv-player-editor-button') > -1 || is_fv_player_screen(editor_button_clicked) || is_fv_player_widgets(editor_button_clicked) || $(editor_button_clicked).parents('.fv-player-gutenberg').find('.fv-player-editor-field').length) {
@@ -3308,7 +3368,7 @@ jQuery(function() {
3308
  }
3309
  }
3310
 
3311
- /*
3312
  * Hide any overlays
3313
  */
3314
  function overlay_hide() {
@@ -3316,7 +3376,7 @@ jQuery(function() {
3316
  return false;
3317
  }
3318
 
3319
- /*
3320
  * Show a certain kind of overlay
3321
  */
3322
  function overlay_show( type, message ) {
@@ -3332,7 +3392,24 @@ jQuery(function() {
3332
  return overlayDiv;
3333
  }
3334
 
3335
- /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3336
  * Populate content of the Embeds tab and show it if there is any content to be set
3337
  *
3338
  * @param string html The OL > LI list of posts which contain the same player.
@@ -3343,42 +3420,7 @@ jQuery(function() {
3343
  get_tabs('embeds').find('td').html(html);
3344
  }
3345
 
3346
- /*
3347
- * Adds another language to subtitle menu
3348
- */
3349
- function subtitle_language_add( sInput, sLang, iTabIndex, sId ) {
3350
- if(!iTabIndex){
3351
- var current = jQuery('.fv-player-tab-subtitles table:visible');
3352
- iTabIndex = current.length && current.data('index') ? current.data('index') : 0;
3353
- }
3354
- var oTab = jQuery('.fv-fp-subtitles').eq(iTabIndex);
3355
- oTab.append( template_subtitles );
3356
-
3357
- var subElement = jQuery('.fv-fp-subtitle:last' , oTab);
3358
-
3359
- if (typeof(sId) !== 'undefined') {
3360
- subElement.attr('data-id_subtitles', sId);
3361
- }
3362
-
3363
- if( sInput ) {
3364
- get_field('subtitles',subElement).val(sInput);
3365
- }
3366
-
3367
- if ( sLang ) {
3368
- if( sLang == 'iw' ) sLang = 'he';
3369
- if( sLang == 'in' ) sLang = 'id';
3370
- if( sLang == 'jw' ) sLang = 'jv';
3371
- if( sLang == 'mo' ) sLang = 'ro';
3372
- if( sLang == 'sh' ) sLang = 'sr';
3373
-
3374
- get_field('subtitles_lang',subElement).val(sLang).change();
3375
- }
3376
-
3377
- editor_resize();
3378
- return false;
3379
- }
3380
-
3381
- function tabs_refresh(){
3382
  var visibleTabs = 0;
3383
  $el_editor.find('a[data-tab]').removeClass('fv_player_interface_hide');
3384
  $el_editor.find('.fv-player-tabs > .fv-player-tab').each(function(){
@@ -3465,7 +3507,7 @@ jQuery(function() {
3465
  Click on Add Another Language (of Subtitles)
3466
  */
3467
  $doc.on('click', '.fv_flowplayer_language_add_link', function() {
3468
- subtitle_language_add(false,true);
3469
  return false;
3470
  });
3471
 
@@ -3562,7 +3604,7 @@ jQuery(function() {
3562
  return false;
3563
  });
3564
 
3565
- /*
3566
  * Removes playlist item
3567
  * Also stores the RTMP server of the first item as that's the only place where
3568
  * it's stored, so in case we are removing the first playlist item, we save it
@@ -3656,6 +3698,7 @@ jQuery(function() {
3656
  }
3657
 
3658
  function init_saved_player_fields( id_player ) {
 
3659
  var
3660
  $id_player_element = $('#fv-player-id_player'),
3661
  $deleted_videos_element = $('#fv-player-deleted_videos'),
@@ -3736,10 +3779,59 @@ jQuery(function() {
3736
  return current_player_db_id;
3737
  },
3738
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3739
  get_edit_lock_removal() {
3740
  return edit_lock_removal;
3741
  },
3742
 
 
 
 
 
3743
  get_shortcode_remains: function() {
3744
  return shortcode_remains;
3745
  },
@@ -3755,8 +3847,43 @@ jQuery(function() {
3755
  set_shortcode_remains: function(value) {
3756
  shortcode_remains = value;
3757
  },
3758
-
3759
  /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3760
  * Show a notice in the overlay above the editor
3761
  *
3762
  * @param {Object} button The button in the overlay that was clicked
@@ -4009,7 +4136,7 @@ function fv_wp_flowplayer_check_for_video_meta_field(fieldName) {
4009
 
4010
  jQuery(document).on('click', '[data-fv-player-editor-export-overlay-copy]', function() {
4011
  var button = this;
4012
- fv_player_clipboard(jQuery('[name=fv_player_copy_to_clipboard]').val(), function() {
4013
  fv_player_editor.overlay_notice( button, 'Text Copied To Clipboard!', 'success', 3000 );
4014
  }, function() {
4015
  fv_player_editor.overlay_notice( button, '<strong>Error copying text into clipboard!</strong><br />Please copy the content of the above text area manually by using CTRL+C (or CMD+C on MAC).', 'error' );
@@ -4045,7 +4172,6 @@ function fv_player_open_preview_window(url, width, height){
4045
  Also used by FV Player Pro and FV Player Pay Per View
4046
  */
4047
  function fv_wp_flowplayer_shortcode_parse_arg( sShortcode, sArg, bHTML, sCallback ) {
4048
-
4049
  var rDoubleQ = new RegExp(sArg+"=\"","g");
4050
  var rSingleQ = new RegExp(sArg+"='","g");
4051
  var rNoQ = new RegExp(sArg+"=[^\"']","g");
@@ -4067,7 +4193,7 @@ function fv_wp_flowplayer_shortcode_parse_arg( sShortcode, sArg, bHTML, sCallbac
4067
  var aOutput = rMatch.exec(sShortcode);
4068
  fv_player_editor.set_shortcode_remains( fv_player_editor.get_shortcode_remains().replace( rMatch, '' ) );
4069
 
4070
- if( bHTML ) {
4071
  aOutput[1] = aOutput[1].replace(/\\"/g, '"').replace(/\\(\[|])/g, '$1');
4072
  }
4073
 
@@ -4082,7 +4208,7 @@ function fv_wp_flowplayer_shortcode_parse_arg( sShortcode, sArg, bHTML, sCallbac
4082
  function fv_wp_flowplayer_subtitle_parse_arg( args ) {
4083
  var input = ('fv_wp_flowplayer_subtitle_parse_arg',args);
4084
  var aLang = input[0].match(/subtitles_([a-z][a-z])/);
4085
- subtitle_language_add( input[1], aLang[1] );
4086
  }
4087
 
4088
 
7
  matcher: /\.(mp4|webm|m3u8)$/i,
8
  // AJAX will return these fields which can be auto-updated via JS
9
  update_fields: ['duration', 'last_video_meta_check'],
10
+ support_thumb_generate: true
11
  }
12
  };
13
 
31
  ajax_save_previous = false,
32
 
33
  current_player_db_id = -1,
34
+ current_player_object = false,
35
+ current_video_db_id = -1,
36
  current_video_to_edit = -1,
37
 
38
  // stores the button which was clicked to open the editor
68
  editing_video_details = false,
69
 
70
  // which playlist item we're currently editing, set to -1 if we're showing playlist view
71
+ item_index = 0,
 
72
 
73
  // are we currently saving data?
74
  is_saving = false,
115
  errors = {};
116
 
117
 
118
+ /**
119
  * A shorthand to save you from all the "fv_wp_flowplayer_field_"
120
  * when selecting fields
121
  *
123
  * you "fv_wp_flowplayer_field_src"
124
  * @param {object|string} where Lets you narrow down the element wher you
125
  * want to locate he field. You can use a jQuery
126
+ * element or a string selector for jQuery.
127
+ * Or TRUE to get the currently open playlist item.
128
  *
129
  * @return {object} The field element
130
  */
132
  var element = false,
133
  selector = '.' + fv_wp_flowplayer_map_names_to_editor_fields(key) + ', [name=' + fv_wp_flowplayer_map_names_to_editor_fields(key) + ']';
134
 
135
+ if( typeof(where) == 'boolean' && where ) {
136
+ where = jQuery('.fv-player-tab [data-index='+item_index+']');
137
+ element = where.find(selector);
138
+
139
+ } else if( where && typeof(where) == "object" ) {
140
  element = where.find(selector);
141
  } else if( where && typeof(where) == "string" ) {
142
  element = $el_editor.find(where).find(selector);
151
  return element;
152
  }
153
 
154
+ /**
155
  * Gives you "src" out of "fv_wp_flowplayer_field_src"
156
  *
157
  * @param {string} name The field name
165
  return name;
166
  }
167
 
168
+ /**
169
  * Gives you the desired tab with video information
170
  *
171
  * @param {int|string} index Number, or first, or last
187
  return $el_editor.find(selector);
188
  }
189
 
190
+ /**
191
  * Gives you all desired tabs of a certain kind
192
  *
193
  * @return {object} The tab elements
287
  cookie: encodeURIComponent(document.cookie),
288
  }, function(json_export_data) {
289
  var overlay = overlay_show('export');
 
290
  overlay.find('textarea').val( $('<div/>').text(json_export_data).html() );
 
 
291
  }).fail(function() {
292
  overlay_show('message', 'An unexpected error has occurred. Please try again.');
293
  });
406
  });
407
  } else {
408
  $spinner.remove();
409
+ $element.show();
410
+ alert(playerID); // show respone message
411
  }
412
  }).fail(function() {
413
+ $spinner.remove();
414
+ $element.show();
415
+ alert('Error');
416
  });
417
 
418
  return false;
776
  // show error overlay if we have errors
777
  var err = fv_player_editor.has_errors();
778
  if ( err ) {
779
+ save_error_show( err );
 
 
 
 
780
  return;
 
 
 
 
 
 
 
 
781
  }
782
 
783
  is_saving = true;
785
 
786
  el_spinner.show();
787
 
788
+ save_error_hide();
789
 
790
  debug_log('Running fv_player_db_save Ajax.');
791
 
793
  action: 'fv_player_db_save',
794
  data: JSON.stringify(ajax_save_this_please),
795
  nonce: fv_player_editor_conf.preview_nonce,
796
+ }, function(response) {
797
+
798
+ if( response.error ) {
799
+ save_error_show( response.error )
800
+ el_spinner.hide();
801
+
802
+ is_saving = false;
803
+
804
+ return;
805
+ }
806
+
807
+ debug_log('player ID after save: '+response.id_player);
808
+
809
+ current_player_object = response;
810
+
811
  try {
812
+ $(response.videos).each( function(k,v) {
813
  var item = $('.fv-player-playlist-item').eq(k);
814
  if( !item.data('id_video') ) {
815
+ item.attr('data-id_video',v.id);
816
+ }
817
+
818
+ if( k == item_index ) {
819
+ debug_log('current_video_db_id after save: '+v.id);
820
+ current_video_db_id = v.id;
821
  }
822
  });
823
 
828
  next = false;
829
  } else {
830
  is_saving = false;
831
+
832
  insert_button_toggle_disabled(false);
833
+
834
  el_spinner.hide();
835
 
836
  $el_save_complete.show().delay( 2500 ).fadeOut(400);
843
  }
844
  overlay_close_waiting_for_save = false;
845
  $.fn.fv_player_box.close();
846
+ } else if ( response.html ) {
847
  // auto-refresh preview
848
+ el_preview_target.html( response.html )
849
 
850
  $doc.trigger('fvp-preview-complete');
851
  }
854
  // add all the data and inputs to page that we need for an existing player
855
  if ( is_unsaved ) {
856
  fv_player_editor.copy_player_button_toggle(false);
857
+ init_saved_player_fields( response.id_player );
858
+ current_player_db_id = response.id_player;
859
  is_unsaved = false;
860
  //is_draft_changed = false;
861
  loading = false;
867
  }
868
 
869
  }, 'json' ).fail( function() {
870
+ save_error_show();
871
 
872
  el_spinner.hide();
873
 
1439
 
1440
 
1441
 
1442
+ /**
1443
  * Initializes shortcode, removes playlist items, hides elements, figures out
1444
  * which actual field is edited - post editor, widget, etc.
1445
  */
1534
  jQuery('#fv-player-shortcode-editor a[data-tab=fv-player-tab-video-files]').trigger('click');
1535
  jQuery('.nav-tab').show;
1536
 
1537
+ reset_editor_ids();
 
1538
 
1539
  editing_video_details = true;
1540
  $el_editor.attr('class','is-singular is-singular-active');
1562
  $doc.trigger('fv-player-editor-init');
1563
  }
1564
 
1565
+ /**
1566
  * Checks all the input fields and created the JavaScript object.
1567
  * Works when saving and also previewing.
1568
  */
1852
  }
1853
  }
1854
 
1855
+ /**
1856
  * Closing the editor
1857
  * * updates the wp-admin -> FV Player screen
1858
  * * sets data for WordPress Heartbeat to unlock the player
1927
  }
1928
 
1929
 
1930
+ /**
1931
  * removes previous values from editor
1932
  * fills new values from shortcode
1933
  *
2166
  debug_log('Finished fv_player_db_load Ajax.',response);
2167
 
2168
  if (response) {
2169
+ if( response.error ) {
2170
+ reset_editor_ids();
2171
+
2172
+ overlay_show('message', response.error );
2173
+
2174
  // The editor failed to load, it's not locked
2175
  edit_lock_removal[current_player_db_id] = 1;
2176
  return;
2186
 
2187
  set_embeds(response['embeds']);
2188
 
2189
+ current_player_object = response;
2190
+
2191
  // fire the player load event to cater for any plugins listening
2192
  var $doc = jQuery(document);
2193
  $doc.trigger('fv_flowplayer_player_meta_load', [response]);
2320
  for (var i in video_meta) {
2321
  // video duration hidden input
2322
  if (['duration', 'last_video_meta_check', 'auto_splash', 'auto_caption'].indexOf(video_meta[i].meta_key) > -1) {
2323
+ var meta_el = jQuery('<input />')
2324
+ .attr('type', 'hidden' )
2325
+ .attr('name', 'fv_wp_flowplayer_field_'+video_meta[i].meta_key )
2326
+ .attr('id', 'fv_wp_flowplayer_field_'+video_meta[i].meta_key )
2327
+ .attr('value', video_meta[i].meta_value )
2328
+ .attr('data-id', video_meta[i].id );
2329
+
2330
+ $video_data_tab.find('#fv_wp_flowplayer_field_src').after(meta_el);
2331
  } else {
2332
  // predefined meta input with field already existing in the dialog
2333
  set_player_field(video_meta[i].meta_key, video_meta[i].meta_value, video_meta[i].id, video_meta[i].id_video);
2455
  fv_wp_flowplayer_shortcode_parse_arg( shortcode, aSubtitlesLangs[i], false, fv_wp_flowplayer_subtitle_parse_arg );
2456
  }
2457
  if(!aSubtitlesLangs){ // move
2458
+ fv_player_editor.subtitle_language_add(false, false );
2459
  }
2460
 
2461
  var smobile = fv_wp_flowplayer_shortcode_parse_arg( shortcode, 'mobile' );
2498
 
2499
  if( srcurl != null && srcurl[1] != null ) {
2500
  get_field('src').val(srcurl[1]);
2501
+ playlist_row.find('.fvp_item_video-filename').text( srcurl[1] );
2502
  }
2503
 
2504
  get_field('width').val(iwidth[1] || '');
2535
 
2536
  if( ssplash != null && ssplash[1] != null ) {
2537
  get_field("splash").val(ssplash[1]);
2538
+
2539
+ var playlist_img = jQuery('<img />')
2540
+ .attr('width', 120 )
2541
+ .attr('src', ssplash[1] );
2542
+
2543
+ playlist_row.find('.fvp_item_splash').html( playlist_img );
2544
  }
2545
 
2546
  var aSubtitles = false;
2650
 
2651
  var caption = aCaptions.shift();
2652
  get_field("caption").val( caption );
2653
+ playlist_row.find('.fvp_item_caption div').text( caption );
2654
  }
2655
 
2656
  var aSplashText = false;
2741
  }
2742
  }
2743
 
2744
+ /**
2745
+ * Calculate FV Player editor popup (Colorbox) size
2746
  */
2747
  function editor_resize() {
2748
  setTimeout(function(){
2764
  },0);
2765
  }
2766
 
2767
+ /**
2768
  * Saving the data
2769
  */
2770
  function editor_submit() {
2845
  data: JSON.stringify(ajax_data),
2846
  nonce: fv_player_editor_conf.preview_nonce
2847
  }, function(response) {
2848
+
2849
+ if( response.error ) {
2850
+ save_error_show(response.error);
2851
+
2852
+ el_spinner.hide();
2853
+ is_saving = false;
2854
+
2855
+ return;
2856
+ }
2857
+
2858
  // player saved, reset draft status
2859
  is_unsaved = false;
2860
  //is_draft_changed = false;
2861
 
2862
  var player = JSON.parse(response);
2863
+ current_player_db_id = parseInt(player.id_player);
2864
  if( current_player_db_id > 0 ) {
2865
  var
2866
  has_store_shortcode_args = false,
2975
  }
2976
  }
2977
 
2978
+ /**
2979
  * Sends new shortcode to editor
2980
  */
2981
  function insert_shortcode( shortcode ) {
3142
 
3143
  if (typeof sSubtitles === 'object' && sSubtitles.length && sSubtitles[0].lang) {
3144
  for (var i in sSubtitles) {
3145
+ fv_player_editor.subtitle_language_add(sSubtitles[i].file, sSubtitles[i].lang, newIndex, sSubtitles[i].id);
3146
  }
3147
  }
3148
 
3204
  get_tabs('video-files').hide();
3205
  var video_tab = get_tab(new_index,'video-files').show();
3206
 
3207
+ if( video_tab.attr('data-id_video') ) {
3208
+ current_video_db_id = video_tab.attr('data-id_video');
3209
+ debug_log('current_video_db_id: '+current_video_db_id);
3210
+ }
3211
+
3212
  get_tabs('subtitles').hide();
3213
  get_tab(new_index,'subtitles').show();
3214
 
3235
  $('.fv_wp_flowplayer_field_subtitles_lang, .subtitle_language_add_link').attr('style',false);
3236
 
3237
  tabs_refresh();
3238
+
3239
+ $doc.trigger('fv-player-editor-video-opened', [ item_index ] );
3240
  }
3241
 
3242
+ /**
3243
  * Recalculate the data-index values for playlist items
3244
  */
3245
  function playlist_index() {
3264
  */
3265
  function playlist_show() {
3266
  item_index = -1;
3267
+ current_video_db_id = -1;
3268
+ debug_log('current_video_db_id: '+current_video_db_id);
3269
 
3270
  editing_video_details = false;
3271
  $el_editor.attr('class','is-playlist-active');
3290
 
3291
  var playlist_row = jQuery('.fv-player-tab-playlist table tbody tr').eq( current.data('index') );
3292
 
3293
+ var video_preview = get_field("splash",current).val(),
3294
+ playlist_img = jQuery('<img />')
3295
+ .attr('width', 120 )
3296
+ .attr('src', video_preview );
3297
+
3298
+ playlist_row.find('.fvp_item_video-thumbnail').html( video_preview.length ? playlist_img : '' );
3299
 
3300
  var video_name = decodeURIComponent(currentUrl).split("/").pop();
3301
  video_name = video_name.replace(/\+/g,' ');
3302
  video_name = video_name.replace(/watch\?v=/,'YouTube: ');
3303
 
3304
+ playlist_row.find('.fvp_item_video-filename').text( video_name );
3305
 
3306
  var playlist_row_div = playlist_row.find('.fvp_item_caption div');
3307
  // do not put in caption if it's loading
3308
  if (!playlist_row_div.hasClass('fv-player-shortcode-editor-small-spinner')) {
3309
+ playlist_row_div.text( get_field("caption",current).val() );
3310
  }
3311
  });
3312
 
3325
  jQuery('.fv-player-tab-playlist').show();
3326
  editor_resize();
3327
  tabs_refresh();
3328
+
3329
+ $doc.trigger('fv-player-editor-video-opened', [ item_index ] );
3330
 
3331
  return false;
3332
  }
3344
  height: height
3345
  };
3346
  }
3347
+
3348
+ function reset_editor_ids() {
3349
+ current_player_db_id = -1;
3350
+ current_player_object = false;
3351
+ current_video_db_id = -1;
3352
+ item_index = 0;
3353
+ }
3354
 
3355
  function set_post_editor_content( html ) {
3356
  if ( editor_button_clicked.className.indexOf('fv-player-editor-button') > -1 || is_fv_player_screen(editor_button_clicked) || is_fv_player_widgets(editor_button_clicked) || $(editor_button_clicked).parents('.fv-player-gutenberg').find('.fv-player-editor-field').length) {
3368
  }
3369
  }
3370
 
3371
+ /**
3372
  * Hide any overlays
3373
  */
3374
  function overlay_hide() {
3376
  return false;
3377
  }
3378
 
3379
+ /**
3380
  * Show a certain kind of overlay
3381
  */
3382
  function overlay_show( type, message ) {
3392
  return overlayDiv;
3393
  }
3394
 
3395
+ /**
3396
+ * Show save error message
3397
+ *
3398
+ * @param {string} message optional mesage
3399
+ */
3400
+ function save_error_show( message = 'Error saving changes.' ) {
3401
+ $el_save_error_p.text( message );
3402
+ $el_save_error.show();
3403
+ }
3404
+
3405
+ /**
3406
+ * Hide save error message
3407
+ */
3408
+ function save_error_hide() {
3409
+ $el_save_error.hide();
3410
+ }
3411
+
3412
+ /**
3413
  * Populate content of the Embeds tab and show it if there is any content to be set
3414
  *
3415
  * @param string html The OL > LI list of posts which contain the same player.
3420
  get_tabs('embeds').find('td').html(html);
3421
  }
3422
 
3423
+ function tabs_refresh() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3424
  var visibleTabs = 0;
3425
  $el_editor.find('a[data-tab]').removeClass('fv_player_interface_hide');
3426
  $el_editor.find('.fv-player-tabs > .fv-player-tab').each(function(){
3507
  Click on Add Another Language (of Subtitles)
3508
  */
3509
  $doc.on('click', '.fv_flowplayer_language_add_link', function() {
3510
+ fv_player_editor.subtitle_language_add(false,true);
3511
  return false;
3512
  });
3513
 
3604
  return false;
3605
  });
3606
 
3607
+ /**
3608
  * Removes playlist item
3609
  * Also stores the RTMP server of the first item as that's the only place where
3610
  * it's stored, so in case we are removing the first playlist item, we save it
3698
  }
3699
 
3700
  function init_saved_player_fields( id_player ) {
3701
+ // TODO: This should not be using inputs
3702
  var
3703
  $id_player_element = $('#fv-player-id_player'),
3704
  $deleted_videos_element = $('#fv-player-deleted_videos'),
3779
  return current_player_db_id;
3780
  },
3781
 
3782
+ get_current_player_object() {
3783
+ return current_player_object;
3784
+ },
3785
+
3786
+ get_current_video_meta( key ) {
3787
+ var video_object = this.get_current_video_object(),
3788
+ video_meta = false;
3789
+
3790
+ if( video_object ) {
3791
+ $( video_object.meta ).each( function(k,v) {
3792
+ if( v.meta_key == key ) {
3793
+ video_meta = v;
3794
+ return false;
3795
+ }
3796
+ } );
3797
+ }
3798
+ return video_meta;
3799
+ },
3800
+
3801
+ get_current_video_meta_value( key ) {
3802
+ var video_object = this.get_current_video_object(),
3803
+ video_id = video_object && video_object.id ? video_object.id : -1,
3804
+ video_meta = this.get_current_video_meta( key );
3805
+
3806
+ if( video_meta ) {
3807
+ debug_log( "Video meta '"+key+"' for #"+video_id, video_meta.meta_value );
3808
+ return video_meta.meta_value;
3809
+ }
3810
+ debug_log( "Video meta '"+key+"' not found for #"+video_id );
3811
+ return false;
3812
+ },
3813
+
3814
+ get_current_video_object() {
3815
+ if( item_index == -1 ) return false;
3816
+
3817
+ if( current_player_object.videos && current_player_object.videos[item_index] ) {
3818
+ return current_player_object.videos[item_index];
3819
+ }
3820
+ return false;
3821
+ },
3822
+
3823
+ get_current_video_db_id() {
3824
+ return current_video_db_id;
3825
+ },
3826
+
3827
  get_edit_lock_removal() {
3828
  return edit_lock_removal;
3829
  },
3830
 
3831
+ get_field( key, where ) {
3832
+ return get_field( key, where );
3833
+ },
3834
+
3835
  get_shortcode_remains: function() {
3836
  return shortcode_remains;
3837
  },
3847
  set_shortcode_remains: function(value) {
3848
  shortcode_remains = value;
3849
  },
3850
+
3851
  /*
3852
+ * Adds another language to subtitle menu
3853
+ */
3854
+ subtitle_language_add: function( sInput, sLang, iTabIndex, sId ) {
3855
+ if(!iTabIndex){
3856
+ var current = jQuery('.fv-player-tab-subtitles table:visible');
3857
+ iTabIndex = current.length && current.data('index') ? current.data('index') : 0;
3858
+ }
3859
+ var oTab = jQuery('.fv-fp-subtitles').eq(iTabIndex);
3860
+ oTab.append( template_subtitles );
3861
+
3862
+ var subElement = jQuery('.fv-fp-subtitle:last' , oTab);
3863
+
3864
+ if (typeof(sId) !== 'undefined') {
3865
+ subElement.attr('data-id_subtitles', sId);
3866
+ }
3867
+
3868
+ if( sInput ) {
3869
+ get_field('subtitles',subElement).val(sInput);
3870
+ }
3871
+
3872
+ if ( sLang ) {
3873
+ if( sLang == 'iw' ) sLang = 'he';
3874
+ if( sLang == 'in' ) sLang = 'id';
3875
+ if( sLang == 'jw' ) sLang = 'jv';
3876
+ if( sLang == 'mo' ) sLang = 'ro';
3877
+ if( sLang == 'sh' ) sLang = 'sr';
3878
+
3879
+ get_field('subtitles_lang',subElement).val(sLang).change();
3880
+ }
3881
+
3882
+ editor_resize();
3883
+ return false;
3884
+ },
3885
+
3886
+ /**
3887
  * Show a notice in the overlay above the editor
3888
  *
3889
  * @param {Object} button The button in the overlay that was clicked
4136
 
4137
  jQuery(document).on('click', '[data-fv-player-editor-export-overlay-copy]', function() {
4138
  var button = this;
4139
+ fv_player_clipboard( jQuery(button).closest('.fv-player-editor-overlay').find('[name=fv_player_copy_to_clipboard]').val(), function() {
4140
  fv_player_editor.overlay_notice( button, 'Text Copied To Clipboard!', 'success', 3000 );
4141
  }, function() {
4142
  fv_player_editor.overlay_notice( button, '<strong>Error copying text into clipboard!</strong><br />Please copy the content of the above text area manually by using CTRL+C (or CMD+C on MAC).', 'error' );
4172
  Also used by FV Player Pro and FV Player Pay Per View
4173
  */
4174
  function fv_wp_flowplayer_shortcode_parse_arg( sShortcode, sArg, bHTML, sCallback ) {
 
4175
  var rDoubleQ = new RegExp(sArg+"=\"","g");
4176
  var rSingleQ = new RegExp(sArg+"='","g");
4177
  var rNoQ = new RegExp(sArg+"=[^\"']","g");
4193
  var aOutput = rMatch.exec(sShortcode);
4194
  fv_player_editor.set_shortcode_remains( fv_player_editor.get_shortcode_remains().replace( rMatch, '' ) );
4195
 
4196
+ if( aOutput && bHTML ) {
4197
  aOutput[1] = aOutput[1].replace(/\\"/g, '"').replace(/\\(\[|])/g, '$1');
4198
  }
4199
 
4208
  function fv_wp_flowplayer_subtitle_parse_arg( args ) {
4209
  var input = ('fv_wp_flowplayer_subtitle_parse_arg',args);
4210
  var aLang = input[0].match(/subtitles_([a-z][a-z])/);
4211
+ fv_player_editor.subtitle_language_add( input[1], aLang[1] );
4212
  }
4213
 
4214
 
models/checker.php CHANGED
@@ -307,9 +307,9 @@ class FV_Player_Checker {
307
  function checker_cron() {
308
  global $fv_fp;
309
  if( $fv_fp->_get_option('video_model_db_checked') && $fv_fp->_get_option('video_meta_model_db_checked') ) {
310
- // get all video IDs for which there is no duration meta_key
311
  global $wpdb;
312
- $aVideos = $wpdb->get_results( "SELECT id, src FROM `{$wpdb->prefix}fv_player_videos` as v left join ( select id_video from {$wpdb->prefix}fv_player_videometa WHERE meta_key = 'duration' ) as m ON v.id = m.id_video where m.id_video IS NULL ORDER BY id DESC" );
313
 
314
  if( $aVideos ) {
315
  foreach( $aVideos AS $objVideo ) {
@@ -323,16 +323,19 @@ class FV_Player_Checker {
323
  if( $last_check && intval($last_check) + 86400 > time() ) {
324
  continue;
325
  }
326
-
 
327
  $meta_data = apply_filters('fv_player_meta_data', $url, false);
328
- if( $meta_data == false) {
 
329
  if( $secured_url = $fv_fp->get_video_src( $url, array( 'dynamic' => true ) ) ) {
330
  $url = $secured_url;
331
  }
332
-
333
- $meta_data['duration'] = $this->check_mimetype(array($url), false, true);
334
- $meta_data['duration'] = $meta_data['duration']['duration'];
335
-
 
336
  }
337
 
338
  if( !empty($meta_data['thumbnail']) ) {
307
  function checker_cron() {
308
  global $fv_fp;
309
  if( $fv_fp->_get_option('video_model_db_checked') && $fv_fp->_get_option('video_meta_model_db_checked') ) {
310
+ // get all video IDs for which there is no duration meta_key or where the duration is "h"
311
  global $wpdb;
312
+ $aVideos = $wpdb->get_results( "SELECT id, src FROM `{$wpdb->prefix}fv_player_videos` as v left join ( select id_video, meta_value from {$wpdb->prefix}fv_player_videometa WHERE meta_key = 'duration' ) as m ON v.id = m.id_video where m.id_video IS NULL OR m.meta_value = 'h' ORDER BY id DESC" );
313
 
314
  if( $aVideos ) {
315
  foreach( $aVideos AS $objVideo ) {
323
  if( $last_check && intval($last_check) + 86400 > time() ) {
324
  continue;
325
  }
326
+
327
+ // TODO: This should change to a proper filter at once
328
  $meta_data = apply_filters('fv_player_meta_data', $url, false);
329
+
330
+ if( $meta_data == false || is_string($meta_data) && strcmp($meta_data,$url) == 0 ) {
331
  if( $secured_url = $fv_fp->get_video_src( $url, array( 'dynamic' => true ) ) ) {
332
  $url = $secured_url;
333
  }
334
+
335
+ if( $check = $this->check_mimetype(array($url), false, true) ) {
336
+ $meta_data = $check;
337
+ }
338
+
339
  }
340
 
341
  if( !empty($meta_data['thumbnail']) ) {
models/conversion.php CHANGED
@@ -13,7 +13,7 @@ class FV_Player_Conversion {
13
  <td><label>Convert JW Player shortcodes to <code>[fvplayer]</code>:</label></td>
14
  <td>
15
  <p class="description">
16
- <input type="button" class="button" value="<?php _e('Convert JW Player shortcodes', 'fv-player-pro'); ?>" style="margin-top: 2ex;" onclick="if( confirm('<?php _e('This converts the [jwplayer] shortcodes into [fvplayer] shortcodes.\n\n Please make sure you backup your database before continuing. You can use revisions to get back to previos versions of your posts as well.', 'fv-player-pro'); ?>') ) location.href='<?php echo wp_nonce_url( site_url('wp-admin/options-general.php?page=fvplayer'), 'convert_jwplayer', 'convert_jwplayer'); ?>'; "/>
17
  </p>
18
  </td>
19
  </tr>
13
  <td><label>Convert JW Player shortcodes to <code>[fvplayer]</code>:</label></td>
14
  <td>
15
  <p class="description">
16
+ <input type="button" class="button" value="<?php _e('Convert JW Player shortcodes', 'fv-player-pro'); ?>" style="margin-top: 2ex;" onclick="if( confirm('<?php _e('This converts the [jwplayer] shortcodes into [fvplayer] shortcodes.\n\n Please make sure you backup your database before continuing. You can use post revisions to get back to previous version of your posts as well.', 'fv-player-pro'); ?>') ) location.href='<?php echo wp_nonce_url( site_url('wp-admin/options-general.php?page=fvplayer'), 'convert_jwplayer', 'convert_jwplayer'); ?>'; "/>
17
  </p>
18
  </td>
19
  </tr>
models/conversion/conversion-base.class.php CHANGED
@@ -52,11 +52,9 @@ abstract class FV_Player_Conversion_Base {
52
  $offset = 0 + intval($_POST['offset2']) + $offset;
53
  $limit = intval($_POST['limit']);
54
 
55
- $total = $this->get_count();
56
-
57
  $posts = $this->get_posts_with_shortcode( $offset, $limit );
58
 
59
- $start = microtime(true);
60
 
61
  foreach( $posts AS $post ) {
62
  $result = $this->convert_one($post);
@@ -73,23 +71,26 @@ abstract class FV_Player_Conversion_Base {
73
 
74
  $conversions_output = array_merge( $conversions_output, $result['output_data'] );
75
 
76
- if( $result['content_updated'] ) {
77
  wp_update_post( array( 'ID' => $post->ID, 'post_content' => $result['new_content'] ) );
78
  }
79
  }
80
 
81
- $percent_done = round ( (($offset + $limit) / $total) * 100 );
82
  $left = $total - ($offset + $limit);
83
 
84
  // build html output
85
  foreach( $conversions_output as $output_data ) {
86
- $html[] = "<tr data-timing='" . number_format(microtime(true) - $start) . "'><td><a href='" . get_edit_post_link( $output_data['ID'] ) . "' target='_blank'> #". $output_data['ID'] . "</a></td><td><a href='" . get_permalink( $output_data['ID'] ) ."' target='_blank'>". $output_data['title'] . "</a></td><td>" . $output_data['type'] . "</td><td>". $output_data['shortcode'] . "</td><td>" . $output_data['output'] . "</td><td>" . $output_data['error'] . "</td></tr>";
 
 
 
 
87
  }
88
 
89
  // response
90
  echo json_encode(
91
  array(
92
- 'timing' => microtime(true) - $start,
93
  'table_rows' => implode( "\n", $html ),
94
  'percent_done' => $percent_done,
95
  'left' => $left,
@@ -144,7 +145,7 @@ abstract class FV_Player_Conversion_Base {
144
 
145
  function conversion_screen() {
146
  global $fv_wp_flowplayer_ver;
147
- wp_enqueue_script('fv-player-convertor', flowplayer::get_plugin_url().'/js/admin-convertor.js', array('jquery'), $fv_wp_flowplayer_ver );
148
 
149
  ?>
150
  <style>
@@ -168,7 +169,13 @@ abstract class FV_Player_Conversion_Base {
168
  <?php echo wpautop($this->help); ?>
169
  <p>
170
  <input type="hidden" name="action" value="rebuild" />
 
 
 
 
171
  <input class="button-primary" type="submit" name="convert" value="Start" />
 
 
172
  </p>
173
 
174
  <p>
@@ -176,7 +183,6 @@ abstract class FV_Player_Conversion_Base {
176
  </p>
177
 
178
  <div id="wrapper" style="display: none"><div id="progress"></div></div>
179
- <div id="loading" style="display: none"></div>
180
 
181
  <table class="wp-list-table widefat fixed striped table-view-list posts">
182
  <thead>
@@ -207,5 +213,9 @@ abstract class FV_Player_Conversion_Base {
207
  </script>
208
  <?php
209
  }
 
 
 
 
210
 
211
  }
52
  $offset = 0 + intval($_POST['offset2']) + $offset;
53
  $limit = intval($_POST['limit']);
54
 
 
 
55
  $posts = $this->get_posts_with_shortcode( $offset, $limit );
56
 
57
+ $total = $this->get_count();
58
 
59
  foreach( $posts AS $post ) {
60
  $result = $this->convert_one($post);
71
 
72
  $conversions_output = array_merge( $conversions_output, $result['output_data'] );
73
 
74
+ if( $this->is_live() && $result['content_updated'] ) {
75
  wp_update_post( array( 'ID' => $post->ID, 'post_content' => $result['new_content'] ) );
76
  }
77
  }
78
 
79
+ $percent_done = $total > 0 ? round ( (($offset + $limit) / $total) * 100 ) : 0;
80
  $left = $total - ($offset + $limit);
81
 
82
  // build html output
83
  foreach( $conversions_output as $output_data ) {
84
+ $html[] = "<tr><td><a href='" . get_edit_post_link( $output_data['ID'] ) . "' target='_blank'> #". $output_data['ID'] . "</a></td><td><a href='" . get_permalink( $output_data['ID'] ) ."' target='_blank'>". $output_data['title'] . "</a></td><td>" . $output_data['type'] . "</td><td>". $output_data['shortcode'] . "</td><td>" . $output_data['output'] . "</td><td>" . $output_data['error'] . "</td></tr>";
85
+ }
86
+
87
+ if( empty($html) && $percent_done == 0 ) {
88
+ $html[] = "<tr><td colspan='6'>No matching players found.</td></tr>";
89
  }
90
 
91
  // response
92
  echo json_encode(
93
  array(
 
94
  'table_rows' => implode( "\n", $html ),
95
  'percent_done' => $percent_done,
96
  'left' => $left,
145
 
146
  function conversion_screen() {
147
  global $fv_wp_flowplayer_ver;
148
+ wp_enqueue_script('fv-player-convertor', flowplayer::get_plugin_url().'/js/admin-convertor.js', array('jquery'), filemtime( dirname(__FILE__).'/../../js/admin-convertor.js' ) );
149
 
150
  ?>
151
  <style>
169
  <?php echo wpautop($this->help); ?>
170
  <p>
171
  <input type="hidden" name="action" value="rebuild" />
172
+
173
+ <?php // This checkbox shows the JS confirmation box when clicked to enable ?>
174
+ <input type="checkbox" name="make-changes" id="make-changes" value="1" onclick="if( this.checked ) return confirm('<?php _e('Please make sure you backup your database before continuing. You can use post revisions to get back to previous version of your posts as well.', 'fv-wordpress-flowplayer') ?>') " /> <label for="make-changes">Make changes</label>
175
+
176
  <input class="button-primary" type="submit" name="convert" value="Start" />
177
+
178
+ <img id="loading" width="16" height="16" src="<?php echo site_url('wp-includes/images/wpspin-2x.gif'); ?>" style="display: none" />
179
  </p>
180
 
181
  <p>
183
  </p>
184
 
185
  <div id="wrapper" style="display: none"><div id="progress"></div></div>
 
186
 
187
  <table class="wp-list-table widefat fixed striped table-view-list posts">
188
  <thead>
213
  </script>
214
  <?php
215
  }
216
+
217
+ function is_live() {
218
+ return !empty($_POST['make-changes']) && $_POST['make-changes'] == 'true';
219
+ }
220
 
221
  }
models/conversion/shortcode2DB.class.php CHANGED
@@ -10,8 +10,33 @@ class FV_Player_Shortcode2Database_Conversion extends FV_Player_Conversion_Base
10
  "'%[fvplayer src=%'",
11
  "'%[flowplayer src=%'",
12
  ),
13
- 'help' => __("This converts the <code>[fvplayer src=...]</code> and <code>[flowplayer src=...]</code> shortcodes into database <code>[fvplayer id=...]</code> shortcodes.\n\nPlease make sure you backup your database before continuing. You can use revisions to get back to previos versions of your posts as well.", 'fv-wordpress-flowplayer')
14
  ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  }
16
 
17
  /**
@@ -21,10 +46,7 @@ class FV_Player_Shortcode2Database_Conversion extends FV_Player_Conversion_Base
21
  */
22
  function get_count() {
23
  global $wpdb;
24
-
25
- $count = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status NOT IN ('inherit','trash') AND (post_content LIKE " . implode(' OR post_content LIKE ',$this->matchers) . ") AND post_type NOT IN ('topic','reply')" );
26
-
27
- return intval($count);
28
  }
29
 
30
  /**
@@ -35,7 +57,8 @@ class FV_Player_Shortcode2Database_Conversion extends FV_Player_Conversion_Base
35
  function get_posts_with_shortcode($offset, $limit) {
36
  global $wpdb;
37
 
38
- $results = $wpdb->get_results( "SELECT ID, post_author, post_date_gmt, post_status, post_title, post_type, post_content FROM {$wpdb->posts} WHERE post_status NOT IN ('inherit','trash') AND (post_content LIKE " . implode(' OR post_content LIKE ', $this->matchers) . ") AND post_type NOT IN ('topic','reply') ORDER BY post_date_gmt DESC LIMIT {$offset},{$limit}");
 
39
 
40
  return $results;
41
  }
@@ -48,8 +71,6 @@ class FV_Player_Shortcode2Database_Conversion extends FV_Player_Conversion_Base
48
  * @return arrray
49
  */
50
  function convert_one( $post ) {
51
- $start = microtime(true);
52
-
53
  $content_updated = false; // track if content was updated
54
  $new_content = $post->post_content; // copy of content for update
55
  $output_data = array(); // output for html
@@ -60,119 +81,67 @@ class FV_Player_Shortcode2Database_Conversion extends FV_Player_Conversion_Base
60
  // match shortcodes in post_content
61
  preg_match_all( '~\[(?:flowplayer|fvplayer).*?\]~', $post->post_content, $matched_shortcodes );
62
 
63
- $supported_atts = array(
64
- 'src',
65
- 'src1',
66
- 'src2',
67
- 'splash',
68
- 'caption',
69
- 'width',
70
- 'height',
71
- 'autoplay',
72
- 'splashend',
73
- 'lightbox '
74
- );
75
-
76
- if( !empty( $matched_shortcodes) ) {
77
  foreach( $matched_shortcodes[0] as $shortcode ) {
78
- $atts = shortcode_parse_atts( trim(rtrim($shortcode,']')) );
79
- $import_atts = array();
80
 
81
- unset( $atts[0] ); // remove [fvplayer or [flowplayer
 
 
 
 
82
 
83
- // ignore db players
84
- if ( isset( $atts['id'] ) ) {
85
- continue;
86
  }
 
 
 
87
 
88
- // check for unsupported args
89
- $unsupported_atts_found = array();
90
- foreach( $atts as $k => $v ) {
91
- if( !in_array( $k, $supported_atts ) ) {
92
- $unsupported_atts_found[] = $k;
93
- } else {
94
- $import_atts[$k] = $v;
95
- }
 
 
 
 
 
 
 
 
 
96
  }
97
 
98
- $output_msg = "Conversion failed.";
99
- $failed_msg = "";
100
-
101
- // check if unsupported args found
102
- if( !empty($unsupported_atts_found) ) {
103
- $failed_msg = "Unsupported argument(s) " . implode(',', $unsupported_atts_found);
104
-
105
- $errors[] = array(
106
- 'ID' => $post->ID,
107
- 'post_title' => $post->post_title,
108
- 'post_link' => get_permalink( $post->ID ),
109
- 'post_edit' => get_edit_post_link( $post->ID ),
110
- 'shortcode' => $shortcode,
111
- 'message' => $failed_msg
112
- );
113
- } else {
114
- // $import_atts['meta'] = array(
115
- // array(
116
- // 'meta_key' => '',
117
- // 'meta_value' => ''
118
- // )
119
- // );
120
-
121
- // only splash, caption and src, src1, src2
122
- $import = array(
123
- // 'player_name' => $post->post_title,
124
- 'meta' => array(
125
- array(
126
- 'meta_key' => 'post_id',
127
- 'meta_value' => $post->ID
128
- ),
129
- array(
130
- 'meta_key' => 'fv_player_conversion',
131
- 'meta_value' => self::class
132
- )
133
- ),
134
- 'author' => $post->post_author,
135
- 'status' => 'published',
136
- 'date_created' => $post->post_date_gmt,
137
- 'width' => isset($atts['width']) ? $atts['width'] : '',
138
- 'height' => isset($atts['height']) ? $atts['height'] : '',
139
- 'autoplay' => isset($atts['autoplay']) ? $atts['autoplay'] : '',
140
- 'videos' => array(
141
- $import_atts
142
- )
143
- );
144
-
145
- global $FV_Player_Db;
146
- $player_id = $FV_Player_Db->import_player_data(false, false, $import);
147
-
148
- if( $player_id > 0 ) {
149
- // echo "Inserted player #".$player_id."\n";
150
- $new_content = str_replace( $shortcode , '[fvplayer id="'.$player_id.'"]', $new_content );
151
- $content_updated = true;
152
- $output_msg = "New FV Player #" . $player_id ;
153
- } else {
154
- $failed_msg = "Error saving FV Player instance";
155
-
156
- $errors[] = array(
157
- 'ID' => $post->ID,
158
- 'post_title' => $post->post_title,
159
- 'post_link' => get_permalink( $post->ID ),
160
- 'post_edit' => get_edit_post_link( $post->ID ),
161
- 'shortcode' => $shortcode,
162
- 'message' => $failed_msg
163
- );
164
  }
165
  }
166
 
167
- $output_data[] = array(
168
- 'timing' => number_format(microtime(true) - $start),
169
- 'ID' => $post->ID,
170
- 'title' => $post->post_title,
171
- 'type' => $post->post_type,
172
- 'shortcode' => $shortcode,
173
- 'output' => $output_msg,
174
- 'error' => $failed_msg
175
- );
176
  }
177
  }
178
  }
@@ -191,13 +160,247 @@ class FV_Player_Shortcode2Database_Conversion extends FV_Player_Conversion_Base
191
  <td><label>Convert <code>[fvplayer src="..."]</code> shortocdes to database-driven <code>[fvplayer id="..."]</code> :</label></td>
192
  <td>
193
  <p class="description">
194
- <input type="button" class="button" value="<?php _e('Convert FV Player shortcodes to DB', 'fv-player-pro'); ?>" style="margin-top: 2ex;" onclick="if( confirm('<?php _e('Please make sure you backup your database before continuing. You can use revisions to get back to previos versions of your posts as well.', 'fv-wordpress-flowplayer') ?>') )location.href='<?php echo admin_url('admin.php?page=' . $this->screen ) ?>'; "/>
195
  </p>
196
  </td>
197
  </tr>
198
  <?php
199
  }
200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  }
202
 
203
  new FV_Player_Shortcode2Database_Conversion;
10
  "'%[fvplayer src=%'",
11
  "'%[flowplayer src=%'",
12
  ),
13
+ 'help' => __("This converts the <code>[fvplayer src=...]</code> and <code>[flowplayer src=...]</code> shortcodes into database <code>[fvplayer id=...]</code> shortcodes.", 'fv-wordpress-flowplayer')
14
  ) );
15
+
16
+ // atts for video that are supported
17
+ $this->supported_video_atts = array(
18
+ 'src',
19
+ 'src1',
20
+ 'src2',
21
+ 'splash',
22
+ );
23
+
24
+ // atts for player that are supported
25
+ $this->supported_player_atts = array(
26
+ 'width',
27
+ 'height',
28
+ 'autoplay',
29
+ 'lightbox',
30
+ 'playlist',
31
+ 'caption',
32
+ 'subtitles',
33
+ 'ab',
34
+ 'chapters',
35
+ 'controlbar',
36
+ 'speed'
37
+ );
38
+
39
+ $this->supported_atts = array_merge( $this->supported_video_atts, $this->supported_player_atts );
40
  }
41
 
42
  /**
46
  */
47
  function get_count() {
48
  global $wpdb;
49
+ return $wpdb->get_var( "SELECT FOUND_ROWS()" );
 
 
 
50
  }
51
 
52
  /**
57
  function get_posts_with_shortcode($offset, $limit) {
58
  global $wpdb;
59
 
60
+ // Each row is the matching wp_posts row or wp_posts row with matching meta_value
61
+ $results = $wpdb->get_results( "SELECT SQL_CALC_FOUND_ROWS ID, post_author, post_date_gmt, post_status, post_title, post_type, post_content FROM {$wpdb->posts} AS p JOIN {$wpdb->postmeta} AS m ON p.ID = m.post_id WHERE post_status NOT IN ('inherit','trash') AND (post_content LIKE " . implode(' OR post_content LIKE ', $this->matchers) . ") AND post_type NOT IN ('topic','reply') OR (meta_value LIKE " . implode(' OR meta_value LIKE ',$this->matchers) . " ) AND meta_key NOT LIKE '%_fv_player_%_backup_%' ANd meta_key NOT LIKE '%_fv_player_%_failed' GROUP BY ID ORDER BY post_date_gmt DESC LIMIT {$offset},{$limit}");
62
 
63
  return $results;
64
  }
71
  * @return arrray
72
  */
73
  function convert_one( $post ) {
 
 
74
  $content_updated = false; // track if content was updated
75
  $new_content = $post->post_content; // copy of content for update
76
  $output_data = array(); // output for html
81
  // match shortcodes in post_content
82
  preg_match_all( '~\[(?:flowplayer|fvplayer).*?\]~', $post->post_content, $matched_shortcodes );
83
 
84
+ if( !empty($matched_shortcodes) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  foreach( $matched_shortcodes[0] as $shortcode ) {
86
+ $result = $this->worker( $shortcode, $post, $new_content );
87
+ if( $result ) {
88
 
89
+ $new_content = $result['new_content'];
90
+ if( $result['content_updated'] ) {
91
+ $content_updated = $result['content_updated'];
92
+ }
93
+ $errors = array_merge( $errors, $result['errors'] );
94
 
95
+ $output_data[] = $result['data'];
 
 
96
  }
97
+ }
98
+ }
99
+ }
100
 
101
+ $meta = get_post_custom( $post->ID );
102
+
103
+ if( is_array($meta) ) {
104
+ foreach( $meta AS $meta_key => $meta_values ) {
105
+ // Skip meta keys created by the conversion
106
+ if(
107
+ preg_match( '~^_fv_player_.*?_backup_~', $meta_key ) ||
108
+ preg_match( '~^_fv_player_.*?_failed$~', $meta_key )
109
+ ) {
110
+ continue;
111
+ }
112
+
113
+ foreach( $meta_values AS $meta_value ) {
114
+
115
+ // Skip serialized meta values, it would be tricky to update
116
+ if( is_serialized($meta_value) ) {
117
+ continue;
118
  }
119
 
120
+ $original_meta_value = $meta_value;
121
+
122
+ $meta_updated = false;
123
+
124
+ preg_match_all( '~\[(?:flowplayer|fvplayer).*?\]~', $meta_value, $matched_shortcodes );
125
+
126
+ if( !empty($matched_shortcodes) ) {
127
+ foreach( $matched_shortcodes[0] as $shortcode ) {
128
+ $result = $this->worker( $shortcode, $post, $meta_value, $meta_key );
129
+ if( $result ) {
130
+ if( $result['content_updated'] ) {
131
+ $meta_updated = $result['content_updated'];
132
+ $meta_value = $result['new_content'];
133
+ }
134
+ $errors = array_merge( $errors, $result['errors'] );
135
+
136
+ $output_data[] = $result['data'];
137
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  }
139
  }
140
 
141
+ if( $this->is_live() && $meta_updated ) {
142
+ update_post_meta( $post->ID, '_fv_player_'.$this->slug.'_backup_'.$meta_key, $original_meta_value );
143
+ update_post_meta( $post->ID, $meta_key, $meta_value, $original_meta_value );
144
+ }
 
 
 
 
 
145
  }
146
  }
147
  }
160
  <td><label>Convert <code>[fvplayer src="..."]</code> shortocdes to database-driven <code>[fvplayer id="..."]</code> :</label></td>
161
  <td>
162
  <p class="description">
163
+ <input type="button" class="button" value="<?php _e('Convert FV Player shortcodes to DB', 'fv-player-pro'); ?>" style="margin-top: 2ex;" onclick="location.href='<?php echo admin_url('admin.php?page=' . $this->screen ) ?>'; "/>
164
  </p>
165
  </td>
166
  </tr>
167
  <?php
168
  }
169
 
170
+ function worker( $shortcode, $post, $new_content, $meta_key = false ) {
171
+ $content_updated = false;
172
+
173
+ $atts = shortcode_parse_atts( trim(rtrim($shortcode,']')) );
174
+ $import_video_atts = array();
175
+ $import_player_atts = array();
176
+
177
+ $import_atts = array();
178
+
179
+ unset( $atts[0] ); // remove [fvplayer or [flowplayer
180
+
181
+ // ignore db players
182
+ if ( isset( $atts['id'] ) ) {
183
+ return false;
184
+ }
185
+
186
+ // check for unsupported args
187
+ $unsupported_atts_found = array();
188
+ foreach( $atts as $k => $v ) {
189
+ if( !in_array( $k, $this->supported_atts ) ) {
190
+ $unsupported_atts_found[] = $k;
191
+ } else {
192
+ $import_atts[$k] = $v;
193
+ }
194
+ }
195
+
196
+ $output_msg = "Conversion failed.";
197
+ $failed_msg = "";
198
+
199
+ // check if unsupported args found
200
+ if( !empty($unsupported_atts_found) ) {
201
+ $failed_msg = "Unsupported argument(s) " . implode(',', $unsupported_atts_found);
202
+
203
+ $errors[] = array(
204
+ 'ID' => $post->ID,
205
+ 'post_title' => $post->post_title,
206
+ 'post_link' => get_permalink( $post->ID ),
207
+ 'post_edit' => get_edit_post_link( $post->ID ),
208
+ 'shortcode' => $shortcode,
209
+ 'message' => $failed_msg
210
+ );
211
+ } else {
212
+ // single video set 0 index
213
+ $video_index = 0;
214
+ $import_video_atts[$video_index] = array();
215
+ // add video atts
216
+ foreach( $this->supported_video_atts as $video_att ) {
217
+ if( isset( $import_atts[$video_att] ) ) {
218
+ $import_video_atts[$video_index][$video_att] = $import_atts[$video_att];
219
+ }
220
+ }
221
+
222
+ // add player atts , parse lightbox, playlist items
223
+ foreach( $this->supported_player_atts as $player_att ) {
224
+ $video_index = 0; // reset video index to 0
225
+ if( isset( $import_atts[$player_att] ) ) {
226
+ if( strcmp( $player_att, 'lightbox' ) == 0 ) { // handle lightbox
227
+ $lightbox_atts = explode(';', $import_atts[$player_att] );
228
+
229
+ $lightbox_count = count( $lightbox_atts );
230
+
231
+ if( $lightbox_count == 2 ) { // lightbox_caption
232
+ $import_player_atts['lightbox_caption'] = $lightbox_atts[1];
233
+ } else if( $lightbox_count == 3 ) { // lightbox_width, lightbox_height
234
+ $import_player_atts['lightbox_width'] = $lightbox_atts[1];
235
+ $import_player_atts['lightbox_height'] = $lightbox_atts[2];
236
+ } else if( $lightbox_count == 4 ) { // lightbox_caption, lightbox_width, lightbox_height
237
+ $import_player_atts['lightbox_width'] = $lightbox_atts[1];
238
+ $import_player_atts['lightbox_height'] = $lightbox_atts[2];
239
+ $import_player_atts['lightbox_caption'] = $lightbox_atts[3];
240
+ }
241
+
242
+ $import_player_atts[$player_att] = $lightbox_atts[0]; // lightbox
243
+ } else if( strcmp( $player_att, 'playlist' ) == 0 ) { // handle playlist
244
+ $playlist_items = explode(';', $import_atts[$player_att]);
245
+ foreach($playlist_items as $item) {
246
+ $video_index++;
247
+ $import_video_atts[$video_index] = array();
248
+
249
+ $item_data = explode(',', $item );
250
+
251
+ // parse src, scr1, scr2 and splash
252
+ if( count( $item_data ) > 1 ) {
253
+ foreach( $item_data as $i => $data ) {
254
+ if( preg_match('~\.(png|gif|jpg|jpe|jpeg)($|\?)~', $data) || stripos($data, 'i.vimeocdn.com') !== false ) { // splash
255
+ $import_video_atts[$video_index]['splash'] = $data;
256
+ } else if( $i > 0 ) { // src1, src2
257
+ $import_video_atts[$video_index]['src'.$i] = $data;
258
+ }
259
+ }
260
+ }
261
+
262
+ $import_video_atts[$video_index]['src'] = $item_data[0]; // src
263
+ }
264
+ } else if(strcmp( $player_att, 'subtitles' ) == 0) { // subtitles
265
+ $subtitles = explode(';', $import_atts[$player_att]);
266
+ foreach( $subtitles as $subtile ) {
267
+ if( !empty( $subtile ) ) {
268
+ if( !isset( $import_video_atts[$video_index]['meta'] ) ) {
269
+ $import_video_atts[$video_index]['meta'] = array();
270
+ }
271
+ $import_video_atts[$video_index]['meta'][] = array( 'meta_key' => 'subtitles', 'meta_value' => esc_url_raw($subtile) );
272
+ }
273
+
274
+ $video_index++;
275
+ }
276
+
277
+ } else if(strcmp( $player_att, 'caption' ) == 0) { // caption
278
+ $replace_from = array('&amp;','\;', '\,'); // escaped characters
279
+ $replace_to = array('<!--amp-->','<!--semicolon-->','<!--comma-->'); // temp replacements
280
+ $unescaped = array( '&', ';', ',' );
281
+ $captions = str_replace( $replace_from, $replace_to, $import_atts[$player_att] );
282
+ $captions = explode(';', $captions);
283
+
284
+ foreach( $captions as $caption ) {
285
+ $caption = str_replace( $replace_to, $unescaped, $caption );
286
+ $import_video_atts[$video_index]['caption'] = $caption;
287
+
288
+ $video_index++;
289
+ }
290
+ } else if(strcmp( $player_att, 'chapters' ) == 0) { // subtitles
291
+ $chapters = explode(';', $import_atts[$player_att]);
292
+ foreach( $chapters as $chapters_vtt ) {
293
+ if( !empty( $chapters_vtt ) ) {
294
+ if( !isset( $import_video_atts[$video_index]['meta'] ) ) {
295
+ $import_video_atts[$video_index]['meta'] = array();
296
+ }
297
+ $import_video_atts[$video_index]['meta'][] = array( 'meta_key' => 'chapters', 'meta_value' => esc_url_raw($chapters_vtt) );
298
+ }
299
+
300
+ $video_index++;
301
+ }
302
+
303
+ } else if(strcmp( $player_att, 'ab' ) == 0) { // subtitles
304
+ if( $import_atts[$player_att] == 'true' ) {
305
+ $import_player_atts[$player_att] = 'on';
306
+ } else if( $import_atts[$player_att] == 'false' ) {
307
+ $import_player_atts[$player_att] = 'off';
308
+ } else {
309
+ $import_player_atts[$player_att] = $import_atts[$player_att];
310
+ }
311
+
312
+ } else if(strcmp( $player_att, 'speed' ) == 0) { // subtitles
313
+ if( $import_atts[$player_att] == 'buttons' ) {
314
+ $import_player_atts[$player_att] = 'yes';
315
+ } else {
316
+ $import_player_atts[$player_att] = $import_atts[$player_att];
317
+ }
318
+
319
+ } else { // other atts
320
+ $import_player_atts[$player_att] = $import_atts[$player_att];
321
+ }
322
+ }
323
+ }
324
+
325
+ // add metadata
326
+ $import_player_atts['meta'] = array(
327
+ array(
328
+ 'meta_key' => 'post_id',
329
+ 'meta_value' => $post->ID
330
+ ),
331
+ array(
332
+ 'meta_key' => 'fv_player_conversion',
333
+ 'meta_value' => self::class
334
+ )
335
+ );
336
+
337
+ // add author
338
+ $import_player_atts['author'] = $post->post_author;
339
+
340
+ // add status
341
+ $import_player_atts['status'] = 'published';
342
+
343
+ // add date_created
344
+ $import_player_atts['date_created'] = $post->post_date_gmt;
345
+
346
+ // add player_name
347
+ // $import_player_atts['player_name'] = 'player_name';
348
+
349
+ // add videos
350
+ $import_player_atts['videos'] = $import_video_atts;
351
+
352
+ // echo '<pre>';
353
+ // var_export($import_player_atts);
354
+ // echo '</pre>';
355
+ // die();
356
+
357
+ if( $this->is_live() ) {
358
+ global $FV_Player_Db;
359
+ $player_id = $FV_Player_Db->import_player_data(false, false, $import_player_atts);
360
+
361
+ if( $player_id > 0 ) {
362
+ // echo "Inserted player #".$player_id."\n";
363
+ $new_content = str_replace( $shortcode , '[fvplayer id="'.$player_id.'"]', $new_content );
364
+ $content_updated = true;
365
+ $output_msg = "New FV Player #" . $player_id ;
366
+ } else {
367
+ $failed_msg = "Error saving FV Player instance";
368
+
369
+ $errors[] = array(
370
+ 'ID' => $post->ID,
371
+ 'post_title' => $post->post_title,
372
+ 'post_link' => get_permalink( $post->ID ),
373
+ 'post_edit' => get_edit_post_link( $post->ID ),
374
+ 'shortcode' => $shortcode,
375
+ 'message' => $failed_msg
376
+ );
377
+ }
378
+
379
+ } else {
380
+ $output_msg = "Would create new FV Player";
381
+ }
382
+ }
383
+
384
+ $type = $post->post_type;
385
+ if( $meta_key ) {
386
+ $type .= '<br />meta_key: <code>'.$meta_key.'</code>';
387
+ }
388
+
389
+ return array(
390
+ 'errors' => $errors,
391
+ 'data' => array(
392
+ 'ID' => $post->ID,
393
+ 'title' => $post->post_title,
394
+ 'type' => $type,
395
+ 'shortcode' => $shortcode,
396
+ 'output' => $output_msg,
397
+ 'error' => $failed_msg
398
+ ),
399
+ 'new_content' => $new_content,
400
+ 'content_updated' => $content_updated
401
+ );
402
+ }
403
+
404
  }
405
 
406
  new FV_Player_Shortcode2Database_Conversion;
models/db-player.php CHANGED
@@ -83,7 +83,7 @@ class FV_Player_Db_Player {
83
  * @return int
84
  */
85
  public function getAuthor() {
86
- return $this->author;
87
  }
88
 
89
  /**
@@ -546,7 +546,6 @@ CREATE TABLE " . self::$db_table_name . " (
546
  }
547
 
548
  $this->initDB($wpdb);
549
- $multiID = is_array($id) || $id === null;
550
 
551
  // don't load anything, if we've only created this instance
552
  // to initialize the database (this comes from list-table.php and unit tests)
@@ -554,193 +553,45 @@ CREATE TABLE " . self::$db_table_name . " (
554
  return;
555
  }
556
 
557
- // if we've got options, fill them in instead of querying the DB,
558
- // since we're storing new player into the DB in such case
559
- if (is_array($options) && count($options) && !isset($options['db_options'])) {
560
-
561
- if( !empty($options['id']) ) {
562
- // ID cannot be set, as it's automatically assigned to all new players
563
- trigger_error('ID of a newly created DB player was provided but will be generated automatically.');
564
- unset($options['id']);
565
- }
566
-
567
- $this->fill_properties($options);
568
-
569
- // add dates for newly created players
570
- if( empty($this->date_created) ) $this->date_created = strftime( '%Y-%m-%d %H:%M:%S', time() );
571
- if( empty($this->date_modified) ) $this->date_modified = strftime( '%Y-%m-%d %H:%M:%S', time() );
572
-
573
- // add author, if we're creating new player and not loading a player from DB for caching purposes
574
- if ( empty($options['author']) ) {
575
- $this->author = get_current_user_id();
576
- }
577
-
578
- if ( empty($options['changed_by']) ) {
579
- if ( !empty($options['author']) ) {
580
- $this->changed_by = $options['author'];
581
- } else {
582
- $this->changed_by = get_current_user_id();
583
- }
584
- }
585
- } else if ($multiID || (is_numeric($id) && $id >= -1)) {
586
  /* @var $cache FV_Player_Db_Player[] */
587
  $cache = ($DB_Cache ? $DB_Cache->getPlayersCache() : array());
588
  $all_cached = false;
589
 
590
- // no options, load data from DB
591
- if ($multiID) {
592
- $query_ids = array();
593
-
594
- if ($id !== null) {
595
- // make sure we have numeric IDs and that they're not cached yet
596
- $query_ids = array();
597
- foreach ( $id as $id_key => $id_value ) {
598
- // check if this player is not cached yet
599
- if ($DB_Cache && !$DB_Cache->isPlayerCached($id_value)) {
600
- $query_ids[ $id_key ] = (int) $id_value;
601
- }
602
-
603
- $id[ $id_key ] = (int) $id_value;
604
- }
605
- }
606
-
607
- if ($id === null || count($query_ids)) {
608
-
609
- // load multiple players via their IDs but a single query and return their values
610
- $select = 'p.*';
611
- if( !empty($options['db_options']) && !empty($options['db_options']['select_fields']) ) $select = 'p.id,'.esc_sql($options['db_options']['select_fields']);
612
-
613
- $where = '';
614
- if( $id !== null ) {
615
- $where = ' WHERE p.id IN('. implode(',', $query_ids).') ';
616
-
617
- // if we have multiple video IDs to load players for, let's prepare a like statement here
618
- } else if( !empty($options['db_options']) && !empty($options['db_options']['search_by_video_ids'])){
619
- $where_like_part = array();
620
- foreach ($options['db_options']['search_by_video_ids'] as $player_video_id) {
621
- $player_video_id = intval($player_video_id);
622
- $where_like_part[] = "(videos = \"$player_video_id\" OR videos LIKE \"%,$player_video_id\" OR videos LIKE \"$player_video_id,%\")";
623
- }
624
-
625
- $where = ' WHERE '.implode(' OR ', $where_like_part);
626
- } else if( !empty( $options['db_options'] ) && array_key_exists( 'author_id', $options['db_options'] ) ) {
627
- $where = ' WHERE author ='.$options['db_options']['author_id'];
628
- }
629
-
630
- $order = '';
631
- if( !empty($options['db_options']) && !empty($options['db_options']['order_by']) ) {
632
- $order = ' ORDER BY '.esc_sql($options['db_options']['order_by']);
633
- if( !empty($options['db_options']['order']) ) $order .= ' '.esc_sql($options['db_options']['order']);
634
- }
635
-
636
- $limit = '';
637
- if( !empty($options['db_options']) && isset($options['db_options']['offset']) && isset($options['db_options']['per_page']) ) {
638
- $limit = ' LIMIT '.intval($options['db_options']['offset']).', '.intval($options['db_options']['per_page']);
639
- }
640
-
641
- $meta_counts_select = '';
642
- $meta_counts_join = '';
643
- if( is_admin() ) {
644
- $meta_counts_select = ',
645
- count(subtitles.id) as subtitles_count,
646
- count(cues.id) as cues_count,
647
- count(chapters.id) as chapters_count,
648
- count(transcript.id) as transcript_count';
649
- $meta_counts_join = 'LEFT JOIN `'.$wpdb->prefix.'fv_player_videometa` AS subtitles ON v.id = subtitles.id_video AND subtitles.meta_key like "subtitles%"
650
- LEFT JOIN `'.$wpdb->prefix.'fv_player_videometa` AS cues ON v.id = cues.id_video AND cues.meta_key like "cues%"
651
- LEFT JOIN `'.$wpdb->prefix.'fv_player_videometa` AS chapters ON v.id = chapters.id_video AND chapters.meta_key = "chapters"
652
- LEFT JOIN `'.$wpdb->prefix.'fv_player_videometa` AS transcript ON v.id = transcript.id_video AND transcript.meta_key = "transcript"
653
- ';
654
- }
655
-
656
- $player_data = $wpdb->get_results('SELECT
657
- '.$select.$meta_counts_select.'
658
- FROM `'.self::$db_table_name.'` AS p
659
- JOIN `'.$wpdb->prefix.'fv_player_videos` AS v on FIND_IN_SET(v.id, p.videos)
660
- '.$meta_counts_join.$where.'
661
- GROUP BY p.id
662
- '.$order.$limit);
663
-
664
- } else if ($id !== null && !count($query_ids)) {
665
- $all_cached = true;
666
- } else {
667
- $player_data = -1;
668
- $this->is_valid = false;
669
- }
670
  } else {
671
- if ($DB_Cache && !$DB_Cache->isPlayerCached($id)) {
672
- // load a single video
673
- $player_data = $wpdb->get_row('
674
- SELECT
675
- '.($options && !empty($options['db_options']) && !empty($options['db_options']['select_fields']) ? 'id,'.esc_sql( $options['db_options']['select_fields'] ) : '*').'
676
- FROM
677
- '.self::$db_table_name.'
678
- WHERE
679
- id = '.intval($id),
680
- ARRAY_A
681
- );
682
- } else if ($DB_Cache && $DB_Cache->isPlayerCached($id)) {
683
- $all_cached = true;
684
- } else {
685
- $player_data = -1;
686
- $this->is_valid = false;
687
- }
688
  }
689
 
690
  if (isset($player_data) && $player_data !== -1 && is_array($player_data) && count($player_data)) {
691
 
692
- // single ID, just populate our own data
693
- if (!$multiID) {
694
- $this->fill_properties($player_data,$DB_Cache);
695
 
696
- // cache this player in DB object
697
- if ($DB_Cache) {
698
- $cache[$this->id] = $this;
699
- }
700
- } else {
701
- // multiple IDs, create new player objects for each of them
702
- // and cache those (except for the first one, which will be
703
- // this actual instance)
704
- $first_done = false;
705
- foreach ($player_data as $db_record) {
706
- if (!$first_done) {
707
- $this->fill_properties($db_record,$DB_Cache);
708
-
709
- $first_done = true;
710
-
711
- // cache this player in DB object
712
- if ($DB_Cache) {
713
- $cache[$db_record->id] = $this;
714
- }
715
- } else {
716
- // create a new video object and populate it with DB values
717
- $record_id = $db_record->id;
718
- // if we don't unset this, we'll get warnings
719
- unset($db_record->id);
720
-
721
- if (self::$DB_Instance && !self::$DB_Instance->isPlayerCached($record_id)) {
722
- $player_object = new FV_Player_Db_Player( null, get_object_vars( $db_record ), self::$DB_Instance );
723
- $player_object->link2db( $record_id );
724
-
725
- // cache this player in DB object
726
- if ($DB_Cache) {
727
- $cache[$record_id] = $player_object;
728
- }
729
- }
730
- }
731
- }
732
  }
 
733
  } else if ($all_cached) {
734
  // fill the data for this class with data of the cached class
735
- if ($multiID) {
736
- $cached_player = $cache[reset($id)];
737
- } else {
738
- $cached_player = $cache[$id];
739
- }
740
 
741
  foreach ($cached_player->getAllDataValues() as $key => $value) {
742
  if( is_array($value) ) continue; // problem with video_objects when exporting
743
-
744
  $this->$key = $value === null ? $value : stripslashes($value);
745
  }
746
 
@@ -756,54 +607,46 @@ CREATE TABLE " . self::$db_table_name . " (
756
  // no players found in DB
757
  $this->is_valid = false;
758
  }
759
- } else {
760
- if ( defined('WP_DEBUG') && WP_DEBUG ) {
761
- trigger_error( 'No options nor a valid ID was provided for DB player instance.' );
762
- }
763
 
764
- return;
765
- }
 
766
 
767
- // update cache, if changed
768
- if (isset($cache) && (!isset($all_cached) || !$all_cached)) {
769
- self::$DB_Instance->setPlayersCache($cache);
770
- }
771
- }
772
 
773
- /**
774
- * Retrieves total number of players in the database.
775
- *
776
- * @return int Returns the total number of players in database.
777
- */
778
- public static function getTotalPlayersCount() {
779
- global $player_ids_when_searching, $wpdb;
780
 
781
- self::init_db_name();
 
 
782
 
783
- // make total the number of players cached, if we've used search
784
- if (isset($_GET['s']) && $_GET['s']) {
785
- if ($player_ids_when_searching) {
786
- $total = count( $player_ids_when_searching );
787
- } else {
788
- $total = 0;
 
 
 
 
 
789
  }
790
  } else {
791
- // if we don't yet have instance of FV_Player_Db_Player created the DB for players
792
- // has not yet been created at all... try to init it first, then select totals
793
- if (!self::$DB_Instance) {
794
- new FV_Player_Db_Player(-1);
795
  }
796
 
797
- $total = $wpdb->get_row( 'SELECT Count(*) AS Total FROM ' . self::$db_table_name );
798
- if ( $total ) {
799
- $total = $total->Total;
800
- }
801
  }
802
 
803
- if ($total) {
804
- return $total;
805
- } else {
806
- return 0;
807
  }
808
  }
809
 
@@ -1021,11 +864,12 @@ CREATE TABLE " . self::$db_table_name . " (
1021
  *
1022
  * @param array $meta_data An optional array of key-value objects
1023
  * with possible meta data for this player.
 
1024
  *
1025
  * @return bool|int Returns record ID if successful, false otherwise.
1026
  * @throws Exception When the underlying metadata object throws.
1027
  */
1028
- public function save($meta_data = array()) {
1029
  global $wpdb;
1030
 
1031
  // prepare SQL
@@ -1057,7 +901,7 @@ CREATE TABLE " . self::$db_table_name . " (
1057
 
1058
  // make sure status is set to "draft" for a new player
1059
  if ( $property == 'status' ) {
1060
- if ( !$is_update ) {
1061
  $value = 'draft';
1062
  } else if ( !$value ) {
1063
  // for existing player, only update if we need to change player status
83
  * @return int
84
  */
85
  public function getAuthor() {
86
+ return intval($this->author);
87
  }
88
 
89
  /**
546
  }
547
 
548
  $this->initDB($wpdb);
 
549
 
550
  // don't load anything, if we've only created this instance
551
  // to initialize the database (this comes from list-table.php and unit tests)
553
  return;
554
  }
555
 
556
+ if ( is_numeric($id) && $id >= -1 ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
557
  /* @var $cache FV_Player_Db_Player[] */
558
  $cache = ($DB_Cache ? $DB_Cache->getPlayersCache() : array());
559
  $all_cached = false;
560
 
561
+ if ($DB_Cache && !$DB_Cache->isPlayerCached($id)) {
562
+ // load a single video
563
+ $player_data = $wpdb->get_row('
564
+ SELECT
565
+ *
566
+ FROM
567
+ '.self::$db_table_name.'
568
+ WHERE
569
+ id = '.intval($id),
570
+ ARRAY_A
571
+ );
572
+ } else if ($DB_Cache && $DB_Cache->isPlayerCached($id)) {
573
+ $all_cached = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
574
  } else {
575
+ $player_data = -1;
576
+ $this->is_valid = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  }
578
 
579
  if (isset($player_data) && $player_data !== -1 && is_array($player_data) && count($player_data)) {
580
 
581
+ $this->fill_properties($player_data,$DB_Cache);
 
 
582
 
583
+ // cache this player in DB object
584
+ if ($DB_Cache) {
585
+ $cache[$this->id] = $this;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  }
587
+
588
  } else if ($all_cached) {
589
  // fill the data for this class with data of the cached class
590
+ $cached_player = $cache[$id];
 
 
 
 
591
 
592
  foreach ($cached_player->getAllDataValues() as $key => $value) {
593
  if( is_array($value) ) continue; // problem with video_objects when exporting
594
+
595
  $this->$key = $value === null ? $value : stripslashes($value);
596
  }
597
 
607
  // no players found in DB
608
  $this->is_valid = false;
609
  }
 
 
 
 
610
 
611
+ // if we've got options, fill them in instead of querying the DB,
612
+ // since we're storing new player into the DB in such case
613
+ } else if (is_array($options)) {
614
 
615
+ if( !empty($options['id']) ) {
616
+ // ID cannot be set, as it's automatically assigned to all new players
617
+ trigger_error('ID of a newly created DB player was provided but will be generated automatically.');
618
+ unset($options['id']);
619
+ }
620
 
621
+ $this->fill_properties($options);
 
 
 
 
 
 
622
 
623
+ // add dates for newly created players
624
+ if( empty($this->date_created) ) $this->date_created = strftime( '%Y-%m-%d %H:%M:%S', time() );
625
+ if( empty($this->date_modified) ) $this->date_modified = strftime( '%Y-%m-%d %H:%M:%S', time() );
626
 
627
+ // add author, if we're creating new player and not loading a player from DB for caching purposes
628
+ if ( empty($options['author']) ) {
629
+ $this->author = get_current_user_id();
630
+ }
631
+
632
+ if ( empty($options['changed_by']) ) {
633
+ if ( !empty($options['author']) ) {
634
+ $this->changed_by = $options['author'];
635
+ } else {
636
+ $this->changed_by = get_current_user_id();
637
+ }
638
  }
639
  } else {
640
+ if ( defined('WP_DEBUG') && WP_DEBUG ) {
641
+ trigger_error( 'No options nor a valid ID was provided for DB player instance.' );
 
 
642
  }
643
 
644
+ return;
 
 
 
645
  }
646
 
647
+ // update cache, if changed
648
+ if (isset($cache) && (!isset($all_cached) || !$all_cached)) {
649
+ self::$DB_Instance->setPlayersCache($cache);
 
650
  }
651
  }
652
 
864
  *
865
  * @param array $meta_data An optional array of key-value objects
866
  * with possible meta data for this player.
867
+ * @param bool $is_import Used when importing to respect the desired player status flag
868
  *
869
  * @return bool|int Returns record ID if successful, false otherwise.
870
  * @throws Exception When the underlying metadata object throws.
871
  */
872
+ public function save($meta_data = array(), $is_import = false ) {
873
  global $wpdb;
874
 
875
  // prepare SQL
901
 
902
  // make sure status is set to "draft" for a new player
903
  if ( $property == 'status' ) {
904
+ if ( !$is_update && !$is_import ) {
905
  $value = 'draft';
906
  } else if ( !$value ) {
907
  // for existing player, only update if we need to change player status
models/db-video-meta.php CHANGED
@@ -78,6 +78,19 @@ class FV_Player_Db_Video_Meta {
78
  return self::$db_table_name;
79
  }
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  /**
82
  * Checks for DB tables existence and creates it as necessary.
83
  *
78
  return self::$db_table_name;
79
  }
80
 
81
+ /**
82
+ * Returns name of the video DB table.
83
+ *
84
+ * @return mixed The name of the video DB table.
85
+ */
86
+ public static function get_db_table_name() {
87
+ if ( !self::$db_table_name ) {
88
+ self::init_db_name();
89
+ }
90
+
91
+ return self::$db_table_name;
92
+ }
93
+
94
  /**
95
  * Checks for DB tables existence and creates it as necessary.
96
  *
models/db-video.php CHANGED
@@ -241,6 +241,8 @@ CREATE TABLE " . self::$db_table_name . " (
241
  }
242
 
243
  $this->initDB($wpdb);
 
 
244
  $multiID = is_array($id);
245
 
246
  // don't load anything, if we've only created this instance
@@ -251,7 +253,7 @@ CREATE TABLE " . self::$db_table_name . " (
251
 
252
  // if we've got options, fill them in instead of querying the DB,
253
  // since we're storing new video into the DB in such case
254
- if (is_array($options) && count($options) && !isset($options['db_options'])) {
255
  foreach ($options as $key => $value) {
256
  if( $key == 'meta' ) continue; // meta is handled elsewhere, but it's part of the object when importing from JSON
257
 
@@ -289,20 +291,12 @@ CREATE TABLE " . self::$db_table_name . " (
289
  // load multiple videos via their IDs but a single query and return their values
290
  if (count($query_ids)) {
291
  $select = '*';
292
- if( !empty($options['db_options']) && !empty($options['db_options']['select_fields']) ) $select = 'id,'.esc_sql($options['db_options']['select_fields']);
293
-
294
  $where = ' WHERE id IN('. implode(',', $query_ids).') ';
295
 
296
  $order = '';
297
- if( !empty($options['db_options']) && !empty($options['db_options']['order_by']) ) {
298
- $order = ' ORDER BY '.esc_sql($options['db_options']['order_by']);
299
- if( !empty($options['db_options']['order']) ) $order .= ' '.esc_sql($options['db_options']['order']);
300
- }
301
 
302
  $limit = '';
303
- if( !empty($options['db_options']) && isset($options['db_options']['offset']) && isset($options['db_options']['per_page']) ) {
304
- $limit = ' LIMIT '.intval($options['db_options']['offset']).', '.intval($options['db_options']['per_page']);
305
- }
306
 
307
  $video_data = $wpdb->get_results('SELECT '.$select.' FROM '.self::$db_table_name.$where.$order.$limit);
308
 
@@ -317,7 +311,7 @@ CREATE TABLE " . self::$db_table_name . " (
317
  // load a single video
318
  $video_data = $wpdb->get_row( '
319
  SELECT
320
- ' . ( $options && ! empty( $options['db_options'] ) && ! empty( $options['db_options']['select_fields'] ) ? 'id,' . esc_sql($options['db_options']['select_fields']) : '*' ) . '
321
  FROM
322
  ' . self::$db_table_name . '
323
  WHERE
241
  }
242
 
243
  $this->initDB($wpdb);
244
+
245
+ // TODO: This should not be here at all
246
  $multiID = is_array($id);
247
 
248
  // don't load anything, if we've only created this instance
253
 
254
  // if we've got options, fill them in instead of querying the DB,
255
  // since we're storing new video into the DB in such case
256
+ if (is_array($options) && count($options) ) {
257
  foreach ($options as $key => $value) {
258
  if( $key == 'meta' ) continue; // meta is handled elsewhere, but it's part of the object when importing from JSON
259
 
291
  // load multiple videos via their IDs but a single query and return their values
292
  if (count($query_ids)) {
293
  $select = '*';
294
+
 
295
  $where = ' WHERE id IN('. implode(',', $query_ids).') ';
296
 
297
  $order = '';
 
 
 
 
298
 
299
  $limit = '';
 
 
 
300
 
301
  $video_data = $wpdb->get_results('SELECT '.$select.' FROM '.self::$db_table_name.$where.$order.$limit);
302
 
311
  // load a single video
312
  $video_data = $wpdb->get_row( '
313
  SELECT
314
+ *
315
  FROM
316
  ' . self::$db_table_name . '
317
  WHERE
models/db.php CHANGED
@@ -21,12 +21,14 @@ class FV_Player_Db {
21
 
22
  private
23
  $edit_lock_timeout_seconds = 120,
 
24
  $videos_cache = array(),
25
  $video_atts_cache = array(),
26
  $video_meta_cache = array(),
27
  $players_cache = array(),
28
  //$player_atts_cache = array(),
29
- $player_meta_cache = array();
 
30
 
31
  public function __construct() {
32
  add_filter('fv_flowplayer_args_pre', array($this, 'getPlayerAttsFromDb'), 5, 1);
@@ -42,7 +44,7 @@ class FV_Player_Db {
42
  add_action( 'wp_ajax_fv_player_db_remove', array($this, 'remove_player') );
43
  add_action( 'wp_ajax_fv_wp_flowplayer_retrieve_video_data', array($this, 'retrieve_video_data') ); // todo: nonce, move into controller/editor.php
44
  add_action( 'wp_ajax_fv_player_db_retrieve_all_players_for_dropdown', array($this, 'retrieve_all_players_for_dropdown') ); // todo: nonce
45
- add_action( 'wp_ajax_fv_player_db_save', array($this, 'db_store_player_data') ); // todo: error message on failure
46
  }
47
 
48
  public function getVideosCache() {
@@ -181,7 +183,7 @@ class FV_Player_Db {
181
 
182
  public function cache_players_and_videos_do( $player_ids ) {
183
  // load all players at once
184
- new FV_Player_Db_Player( $player_ids, array(), $this );
185
 
186
  // load all player meta
187
  new FV_Player_Db_Player_Meta( null, array( 'id_player' => $player_ids ), $this );
@@ -198,6 +200,55 @@ class FV_Player_Db {
198
  }
199
  }
200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  /**
202
  * Retrieves data for all players table shown in admin.
203
  *
@@ -211,19 +262,27 @@ class FV_Player_Db {
211
  * @return array Returns an array of all list page results to be displayed.
212
  * @throws Exception When the underlying FV_Player_Db_Video class generates an error.
213
  */
214
- public static function getListPageData($order_by, $order, $offset, $per_page, $single_id = null, $search = null) {
215
- global $player_ids_when_searching, $FV_Player_Db; // this is an instance of this same class, but since we're in static context, we need to access this globally like that... sorry :P
216
-
217
  // sanitize variables
218
  $order = (in_array($order, array('asc', 'desc')) ? $order : 'asc');
219
- $order_by = (in_array($order_by, array('id', 'player_name', 'date_created', 'author', 'subtitles_count', 'chapters_count', 'transcript_count')) ? $order_by : 'id');
220
  $author_id = get_current_user_id();
221
  $cannot_edit_other_posts = !current_user_can('edit_others_posts');
222
 
223
  // load single player, as requested by the user
224
  if ($single_id) {
225
- new FV_Player_Db_Player( $single_id, array(), $FV_Player_Db );
226
  } else if ($search) {
 
 
 
 
 
 
 
 
 
 
227
  // search for videos that are consistent with the search text
228
  // and load their players only
229
  $vids = FV_Player_Db_Video::search(array('src', 'src1', 'src2', 'caption', 'splash', 'splash_text'), $search, true, 'OR', 'id');
@@ -236,8 +295,8 @@ class FV_Player_Db {
236
  $player_video_ids[] = $db_record->id;
237
  }
238
 
239
- // cache this, so we can use this in the FV_Player_Db_Player::getTotalPlayersCount() method
240
- $player_ids_when_searching = $player_video_ids;
241
 
242
  $db_options = array(
243
  'select_fields' => 'player_name, date_created, videos, author, status',
@@ -252,10 +311,14 @@ class FV_Player_Db {
252
  $db_options['author_id'] = $author_id;
253
  }
254
 
255
- new FV_Player_Db_Player( null, array(
256
- 'db_options' => $db_options
257
- ), $FV_Player_Db );
258
  }
 
 
 
 
 
 
259
  } else {
260
  // load all players, which will put them into the cache automatically
261
 
@@ -271,15 +334,13 @@ class FV_Player_Db {
271
  $db_options['author_id'] = $author_id;
272
  }
273
 
274
- new FV_Player_Db_Player( null, array(
275
- 'db_options' => $db_options
276
- ), $FV_Player_Db );
277
  }
278
 
279
  global $fv_fp;
280
  $stats_enabled = $fv_fp->_get_option('video_stats_enable');
281
 
282
- $players = $FV_Player_Db->getPlayersCache();
283
 
284
  // get all video IDs used in all players
285
  if ($players && count($players)) {
@@ -293,11 +354,8 @@ class FV_Player_Db {
293
 
294
  // load all videos data at once
295
  if (count($videos)) {
296
- $vids_data = new FV_Player_Db_Video( $videos, array(
297
- 'db_options' => array(
298
- 'select_fields' => 'caption, src, splash'
299
- )
300
- ), $FV_Player_Db );
301
 
302
  // reset $videos variable and index all of our video data,
303
  // so they are easily accessible when building the resulting
@@ -305,8 +363,8 @@ class FV_Player_Db {
305
  if ($vids_data) {
306
  /* @var FV_Player_Db_Video[] $videos */
307
  $videos = array();
308
- if (count($FV_Player_Db->getVideosCache())) {
309
- foreach ( $FV_Player_Db->getVideosCache() as $video_object ) {
310
  $videos[ $video_object->getId() ] = $video_object;
311
  }
312
  }
@@ -352,15 +410,8 @@ class FV_Player_Db {
352
  // assemble video splash
353
  if (isset($videos[ $video_id ]) && $videos[ $video_id ]->getSplash()) {
354
  // use splash with caption / filename in a span
355
- if ( isset($videos[ $video_id ]) && $caption ) {
356
- $txt = $caption;
357
- } else {
358
- $txt = esc_attr($caption_src);
359
- }
360
-
361
  $splash = apply_filters( 'fv_flowplayer_playlist_splash', $videos[ $video_id ]->getSplash() );
362
-
363
- $result_row->thumbs[] = '<div class="fv_player_splash_list_preview"><img src="'.esc_attr($splash).'" width="100" alt="'.esc_attr($txt).'" title="'.esc_attr($txt).'" loading="lazy" /><span>' . $txt . '</span></div>';
364
  } else if ( isset($videos[ $video_id ]) && $caption ) {
365
  // use caption
366
  $result_row->thumbs[] = '<div class="fv_player_splash_list_preview fv_player_list_preview_no_splash" title="' . esc_attr($caption) . '"><span>' . $caption . '</span></div>';
@@ -792,6 +843,60 @@ class FV_Player_Db {
792
  return $atts;
793
  }
794
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
795
 
796
  /**
797
  * Stored player data in a database from the POST data sent via AJAX
@@ -810,12 +915,24 @@ class FV_Player_Db {
810
  $player_options = array();
811
  $video_ids = array();
812
 
 
 
 
813
  $post_data = null;
814
  if( is_array($data) ) {
815
  $post_data = $data;
816
- } else if( !empty($_POST['data']) && wp_verify_nonce( $_POST['nonce'],"fv-player-preview-".get_current_user_id() ) ) {
817
  if( json_decode( stripslashes($_POST['data']) ) ) {
818
  $post_data = json_decode( stripslashes($_POST['data']), true );
 
 
 
 
 
 
 
 
 
819
  }
820
  }
821
 
@@ -1027,22 +1144,9 @@ class FV_Player_Db {
1027
  $id = $player->save($player_meta);
1028
 
1029
  if ($id) {
1030
- $output = array( 'id' => $id );
1031
- $videos = array();
1032
- foreach( $player->getVideos() AS $video ) {
1033
- $videos[] = $video->getId();
1034
- }
1035
-
1036
- do_action('fv_player_db_save', $id);
1037
-
1038
- $output = array( 'id' => $id, 'videos' => $videos );
1039
-
1040
- $preview_data = $fv_fp->build_min_player( false, array( 'id' => $id ) );
1041
- $output['html'] = $preview_data['html'];
1042
-
1043
- echo wp_json_encode( $output );
1044
  } else {
1045
- echo -1;
1046
  }
1047
  } else {
1048
  $player->link2meta( $player_meta );
@@ -1067,12 +1171,12 @@ class FV_Player_Db {
1067
  global $fv_fp;
1068
 
1069
  if (isset($_POST['playerID']) && is_numeric($_POST['playerID']) && intval($_POST['playerID']) == $_POST['playerID']) {
1070
- $out = array();
1071
-
1072
  if( defined('DOING_AJAX') && DOING_AJAX &&
1073
  ( empty($_POST['nonce']) || !wp_verify_nonce( $_POST['nonce'],"fv-player-db-load-".get_current_user_id() ) )
1074
  ) {
1075
- die('Security check failed'); // todo: this doesn't show up for the user
 
1076
  }
1077
 
1078
  // load player and its videos from DB
@@ -1081,8 +1185,18 @@ class FV_Player_Db {
1081
  die();
1082
  }
1083
 
1084
- // check player's meta data for an edit lock
1085
  $userID = get_current_user_id();
 
 
 
 
 
 
 
 
 
 
 
1086
  if ($fv_fp->current_player() && count($fv_fp->current_player()->getMetaData())) {
1087
  $edit_lock_found = false;
1088
  foreach ($fv_fp->current_player()->getMetaData() as $meta_object) {
@@ -1112,7 +1226,7 @@ class FV_Player_Db {
1112
  if( !empty($user->display_name) ) $name = $user->display_name;
1113
  if( !empty($user->user_nicename) ) $name = $user->user_nicename;
1114
  }
1115
- echo $name." is editing this player at the moment. Please try again later.";
1116
  die();
1117
  }
1118
  } else {
@@ -1146,61 +1260,164 @@ class FV_Player_Db {
1146
  }
1147
  }
1148
 
1149
- // fill the $out variable with player data
1150
- $out = array_merge($out, $fv_fp->current_player()->getAllDataValues());
1151
 
1152
- // load player meta data
1153
- $meta = $fv_fp->current_player()->getMetaData();
1154
- foreach ($meta as $meta_object) {
1155
- if (!isset($out['meta'])) {
1156
- $out['meta'] = array();
1157
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1158
 
1159
- $out['meta'][] = $meta_object->getAllDataValues();
 
 
 
 
1160
  }
 
1161
 
1162
- unset($out['video_objects'], $out['videos']);
 
 
 
 
1163
 
1164
- // fill the $out variable with video data
1165
- $out['videos'] = array();
1166
- foreach ($fv_fp->current_player()->getVideos() as $video) {
1167
- // load video values
1168
- $vid = $video->getAllDataValues();
1169
- $vid['meta'] = array();
1170
 
1171
- // load all meta data
1172
- $meta = $video->getMetaData();
 
1173
 
1174
- foreach ($meta as $meta_object) {
1175
- $vid['meta'][] = $meta_object->getAllDataValues();
1176
- }
 
 
1177
 
1178
- $out['videos'][] = $vid;
 
1179
  }
1180
 
1181
- // load posts where this player is embedded
1182
- $embeds_html = '';
1183
- if( $posts = $fv_fp->current_player()->getMetaValue('post_id') ) {
1184
- foreach( $posts AS $post_id ) {
1185
- $embeds_html .= '<li><a href="'.get_permalink($post_id).'" target="_blank">'.get_the_title($post_id).'</a></li>';
 
 
 
 
 
 
 
 
 
 
 
 
1186
  }
1187
  }
1188
- if( $embeds_html ) {
1189
- $out['embeds'] = '<ol>'.$embeds_html.'</ol>';
 
 
 
 
 
 
1190
  }
 
1191
 
1192
- $preview_data = $fv_fp->build_min_player( false, array( 'id' => $fv_fp->current_player()->getId() ) );
1193
- $out['html'] = $preview_data['html'];
 
 
1194
 
1195
- header('Content-Type: application/json');
1196
- if (version_compare(phpversion(), '5.3', '<')) {
1197
- echo json_encode($out);
1198
- } else {
1199
- echo json_encode($out, true);
 
 
 
 
 
 
 
 
 
 
 
1200
  }
 
 
 
 
 
 
 
1201
  }
1202
 
1203
- wp_die();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1204
  }
1205
 
1206
  /**
@@ -1308,11 +1525,20 @@ class FV_Player_Db {
1308
  ) {
1309
  die('Security check failed');
1310
  }
1311
-
1312
  if ( $id ) {
1313
  // first, load the player
1314
  $player = new FV_Player_Db_Player($id, array(), $this);
1315
  if ($player && $player->getIsValid()) {
 
 
 
 
 
 
 
 
 
1316
  $export_data = $player->export();
1317
 
1318
  // load player meta data
@@ -1454,16 +1680,10 @@ class FV_Player_Db {
1454
  $player->setVideos(implode(',', $player_video_ids));
1455
 
1456
  // save player
1457
- $id_player = $player->save();
1458
-
1459
- // create player meta, if any
1460
- if (isset($data['meta'])) {
1461
- foreach ($data['meta'] as $meta_data) {
1462
- $meta_object = new FV_Player_Db_Player_Meta(null, $meta_data, $FV_Player_Db);
1463
- $meta_object->link2db($id_player, true);
1464
- $meta_object->save();
1465
- }
1466
- }
1467
 
1468
  } catch (Exception $e) {
1469
  if (WP_DEBUG) {
@@ -1507,6 +1727,16 @@ class FV_Player_Db {
1507
  // first, load the player
1508
  $player = new FV_Player_Db_Player($_POST['playerID'], array(), $this);
1509
  if ($player && $player->getIsValid()) {
 
 
 
 
 
 
 
 
 
 
1510
  // remove the player
1511
  if ($player->delete()) {
1512
  echo 1;
@@ -1531,6 +1761,17 @@ class FV_Player_Db {
1531
  */
1532
  public function clone_player() {
1533
  if (isset($_POST['playerID']) && is_numeric($_POST['playerID'])) {
 
 
 
 
 
 
 
 
 
 
 
1534
  $export_data = $this->export_player_data(null, false);
1535
 
1536
  // do not clone information about where the player is embeded
@@ -1608,7 +1849,7 @@ class FV_Player_Db {
1608
  * into a dropdown in the front-end.
1609
  */
1610
  public function retrieve_all_players_for_dropdown() {
1611
- $players = $this->getListPageData('date_created', 'desc', null, null);
1612
  $json_data = array();
1613
 
1614
  foreach ($players as $player) {
21
 
22
  private
23
  $edit_lock_timeout_seconds = 120,
24
+ $valid_order_by = array('id', 'player_name', 'date_created', 'author', 'subtitles_count', 'chapters_count', 'transcript_count'),
25
  $videos_cache = array(),
26
  $video_atts_cache = array(),
27
  $video_meta_cache = array(),
28
  $players_cache = array(),
29
  //$player_atts_cache = array(),
30
+ $player_meta_cache = array(),
31
+ $player_ids_when_searching;
32
 
33
  public function __construct() {
34
  add_filter('fv_flowplayer_args_pre', array($this, 'getPlayerAttsFromDb'), 5, 1);
44
  add_action( 'wp_ajax_fv_player_db_remove', array($this, 'remove_player') );
45
  add_action( 'wp_ajax_fv_wp_flowplayer_retrieve_video_data', array($this, 'retrieve_video_data') ); // todo: nonce, move into controller/editor.php
46
  add_action( 'wp_ajax_fv_player_db_retrieve_all_players_for_dropdown', array($this, 'retrieve_all_players_for_dropdown') ); // todo: nonce
47
+ add_action( 'wp_ajax_fv_player_db_save', array($this, 'db_store_player_data') );
48
  }
49
 
50
  public function getVideosCache() {
183
 
184
  public function cache_players_and_videos_do( $player_ids ) {
185
  // load all players at once
186
+ $this->query_players( array( 'ids' => $player_ids ) );
187
 
188
  // load all player meta
189
  new FV_Player_Db_Player_Meta( null, array( 'id_player' => $player_ids ), $this );
200
  }
201
  }
202
 
203
+ /**
204
+ * Retrieves total number of players in the database.
205
+ *
206
+ * @return int Returns the total number of players in database.
207
+ */
208
+ public function getListPageCount() {
209
+ global $wpdb;
210
+
211
+ $cannot_edit_other_posts = !current_user_can('edit_others_posts');
212
+ $author_id = get_current_user_id();
213
+
214
+ // make total the number of players cached, if we've used search
215
+ if (isset($_GET['s']) && $_GET['s']) {
216
+ if( $this->player_ids_when_searching ) {
217
+ $db_options = array(
218
+ 'select_fields' => 'player_name, date_created, videos, author, status',
219
+ 'count' => true,
220
+ 'search_by_video_ids' => $this->player_ids_when_searching
221
+ );
222
+
223
+ if( $cannot_edit_other_posts ) {
224
+ $db_options['author_id'] = $author_id;
225
+ }
226
+
227
+ $total = $this->query_players( $db_options );
228
+ } else {
229
+ $total = 0;
230
+ }
231
+ } else {
232
+ $query = 'SELECT Count(*) AS Total FROM ' . $wpdb->prefix .'fv_player_players';
233
+
234
+ if( $cannot_edit_other_posts ) {
235
+
236
+ $query .= ' WHERE author = ' . $author_id;
237
+ }
238
+
239
+ $total = $wpdb->get_row( $query );
240
+ if ( $total ) {
241
+ $total = $total->Total;
242
+ }
243
+ }
244
+
245
+ if ($total) {
246
+ return $total;
247
+ } else {
248
+ return 0;
249
+ }
250
+ }
251
+
252
  /**
253
  * Retrieves data for all players table shown in admin.
254
  *
262
  * @return array Returns an array of all list page results to be displayed.
263
  * @throws Exception When the underlying FV_Player_Db_Video class generates an error.
264
  */
265
+ public function getListPageData($order_by, $order, $offset, $per_page, $single_id = null, $search = null) {
 
 
266
  // sanitize variables
267
  $order = (in_array($order, array('asc', 'desc')) ? $order : 'asc');
268
+ $order_by = (in_array($order_by, $this->valid_order_by) ? $order_by : 'id');
269
  $author_id = get_current_user_id();
270
  $cannot_edit_other_posts = !current_user_can('edit_others_posts');
271
 
272
  // load single player, as requested by the user
273
  if ($single_id) {
274
+ new FV_Player_Db_Player( $single_id, array(), $this );
275
  } else if ($search) {
276
+
277
+ $direct_hit_cache = false;
278
+
279
+ // Try to load the player which ID matches the search query it it's a number
280
+ if( is_numeric($search) ) {
281
+ new FV_Player_Db_Player( $search, array(), $this );
282
+
283
+ $direct_hit_cache = $this->getPlayersCache();
284
+ }
285
+
286
  // search for videos that are consistent with the search text
287
  // and load their players only
288
  $vids = FV_Player_Db_Video::search(array('src', 'src1', 'src2', 'caption', 'splash', 'splash_text'), $search, true, 'OR', 'id');
295
  $player_video_ids[] = $db_record->id;
296
  }
297
 
298
+ // cache this, so we can use this in the FV_Player_Db_Player::getListPageCount() method
299
+ $this->player_ids_when_searching = $player_video_ids;
300
 
301
  $db_options = array(
302
  'select_fields' => 'player_name, date_created, videos, author, status',
311
  $db_options['author_id'] = $author_id;
312
  }
313
 
314
+ $this->query_players( $db_options );
 
 
315
  }
316
+
317
+ if( is_array($direct_hit_cache) ) {
318
+ $cache = $this->getPlayersCache();
319
+ $this->setPlayersCache( array_merge( $direct_hit_cache, $cache ) );
320
+ }
321
+
322
  } else {
323
  // load all players, which will put them into the cache automatically
324
 
334
  $db_options['author_id'] = $author_id;
335
  }
336
 
337
+ $this->query_players( $db_options );
 
 
338
  }
339
 
340
  global $fv_fp;
341
  $stats_enabled = $fv_fp->_get_option('video_stats_enable');
342
 
343
+ $players = $this->getPlayersCache();
344
 
345
  // get all video IDs used in all players
346
  if ($players && count($players)) {
354
 
355
  // load all videos data at once
356
  if (count($videos)) {
357
+ // TODO: This class should not provide search
358
+ $vids_data = new FV_Player_Db_Video( $videos, array(), $this );
 
 
 
359
 
360
  // reset $videos variable and index all of our video data,
361
  // so they are easily accessible when building the resulting
363
  if ($vids_data) {
364
  /* @var FV_Player_Db_Video[] $videos */
365
  $videos = array();
366
+ if (count($this->getVideosCache())) {
367
+ foreach ( $this->getVideosCache() as $video_object ) {
368
  $videos[ $video_object->getId() ] = $video_object;
369
  }
370
  }
410
  // assemble video splash
411
  if (isset($videos[ $video_id ]) && $videos[ $video_id ]->getSplash()) {
412
  // use splash with caption / filename in a span
 
 
 
 
 
 
413
  $splash = apply_filters( 'fv_flowplayer_playlist_splash', $videos[ $video_id ]->getSplash() );
414
+ $result_row->thumbs[] = '<div class="fv_player_splash_list_preview"><img src="'.esc_attr($splash).'" width="100" alt="'.esc_attr($caption).'" title="'.esc_attr($caption).'" loading="lazy" /><span>' . $caption . '</span></div>';
 
415
  } else if ( isset($videos[ $video_id ]) && $caption ) {
416
  // use caption
417
  $result_row->thumbs[] = '<div class="fv_player_splash_list_preview fv_player_list_preview_no_splash" title="' . esc_attr($caption) . '"><span>' . $caption . '</span></div>';
843
  return $atts;
844
  }
845
 
846
+ public function db_load_player_data( $id ) {
847
+ global $fv_fp;
848
+
849
+ $this->getPlayerAttsFromDb( array( 'id' => $id ) );
850
+
851
+ // fill the $out variable with player data
852
+ $out = $fv_fp->current_player()->getAllDataValues();
853
+
854
+ // load player meta data
855
+ $meta = $fv_fp->current_player()->getMetaData();
856
+ foreach ($meta as $meta_object) {
857
+ if (!isset($out['meta'])) {
858
+ $out['meta'] = array();
859
+ }
860
+
861
+ $out['meta'][] = $meta_object->getAllDataValues();
862
+ }
863
+
864
+ unset($out['video_objects'], $out['videos']);
865
+
866
+ // fill the $out variable with video data
867
+ $out['videos'] = array();
868
+ foreach ($fv_fp->current_player()->getVideos() as $video) {
869
+ // load video values
870
+ $vid = $video->getAllDataValues();
871
+ $vid['meta'] = array();
872
+
873
+ // load all meta data
874
+ $meta = $video->getMetaData();
875
+
876
+ foreach ($meta as $meta_object) {
877
+ $vid['meta'][] = $meta_object->getAllDataValues();
878
+ }
879
+
880
+ $out['videos'][] = $vid;
881
+ }
882
+
883
+ // load posts where this player is embedded
884
+ $embeds_html = '';
885
+ if( $posts = $fv_fp->current_player()->getMetaValue('post_id') ) {
886
+ foreach( $posts AS $post_id ) {
887
+ $embeds_html .= '<li><a href="'.get_permalink($post_id).'" target="_blank">'.get_the_title($post_id).'</a></li>';
888
+ }
889
+ }
890
+ if( $embeds_html ) {
891
+ $out['embeds'] = '<ol>'.$embeds_html.'</ol>';
892
+ }
893
+
894
+ $preview_data = $fv_fp->build_min_player( false, array( 'id' => $fv_fp->current_player()->getId() ) );
895
+ $out['html'] = $preview_data['html'];
896
+
897
+ return $out;
898
+ }
899
+
900
 
901
  /**
902
  * Stored player data in a database from the POST data sent via AJAX
915
  $player_options = array();
916
  $video_ids = array();
917
 
918
+ $cannot_edit_other_posts = !current_user_can('edit_others_posts');
919
+ $user_id = get_current_user_id();
920
+
921
  $post_data = null;
922
  if( is_array($data) ) {
923
  $post_data = $data;
924
+ } else if( !empty($_POST['data']) && wp_verify_nonce( $_POST['nonce'],"fv-player-preview-".$user_id ) ) {
925
  if( json_decode( stripslashes($_POST['data']) ) ) {
926
  $post_data = json_decode( stripslashes($_POST['data']), true );
927
+
928
+ // check if user can update player
929
+ if(!empty($post_data['update']) && $cannot_edit_other_posts ) {
930
+ $player_to_check = new FV_Player_Db_Player(intval($post_data['update']), array(), $FV_Player_Db);
931
+
932
+ if( $player_to_check->getAuthor() !== $user_id ) {
933
+ wp_send_json( array( 'error' => 'Security check failed.' ) );
934
+ }
935
+ }
936
  }
937
  }
938
 
1144
  $id = $player->save($player_meta);
1145
 
1146
  if ($id) {
1147
+ echo wp_json_encode( $this->db_load_player_data( $id ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
1148
  } else {
1149
+ wp_send_json( array( 'error' => 'Failed to save player.' ) );
1150
  }
1151
  } else {
1152
  $player->link2meta( $player_meta );
1171
  global $fv_fp;
1172
 
1173
  if (isset($_POST['playerID']) && is_numeric($_POST['playerID']) && intval($_POST['playerID']) == $_POST['playerID']) {
1174
+
 
1175
  if( defined('DOING_AJAX') && DOING_AJAX &&
1176
  ( empty($_POST['nonce']) || !wp_verify_nonce( $_POST['nonce'],"fv-player-db-load-".get_current_user_id() ) )
1177
  ) {
1178
+ wp_send_json( array( 'error' => 'Security check failed.' ) );
1179
+ die();
1180
  }
1181
 
1182
  // load player and its videos from DB
1185
  die();
1186
  }
1187
 
 
1188
  $userID = get_current_user_id();
1189
+ $cannot_edit_other_posts = !current_user_can('edit_others_posts');
1190
+
1191
+ if( $cannot_edit_other_posts && $fv_fp->current_player() ) {
1192
+ $author = $fv_fp->current_player()->getAuthor();
1193
+ if( $userID !== $author ) {
1194
+ wp_send_json( array( 'error' => 'You don\'t have permission to edit this player.' ) );
1195
+ die();
1196
+ }
1197
+ }
1198
+
1199
+ // check player's meta data for an edit lock
1200
  if ($fv_fp->current_player() && count($fv_fp->current_player()->getMetaData())) {
1201
  $edit_lock_found = false;
1202
  foreach ($fv_fp->current_player()->getMetaData() as $meta_object) {
1226
  if( !empty($user->display_name) ) $name = $user->display_name;
1227
  if( !empty($user->user_nicename) ) $name = $user->user_nicename;
1228
  }
1229
+ wp_send_json( array( 'error' => $name." is editing this player at the moment. Please try again later." ) );
1230
  die();
1231
  }
1232
  } else {
1260
  }
1261
  }
1262
 
1263
+ $out = $this->db_load_player_data( $_POST['playerID'] );
 
1264
 
1265
+ header('Content-Type: application/json');
1266
+ if (version_compare(phpversion(), '5.3', '<')) {
1267
+ echo json_encode($out);
1268
+ } else {
1269
+ echo json_encode($out, true);
1270
+ }
1271
+ }
1272
+
1273
+ wp_die();
1274
+ }
1275
+
1276
+ /**
1277
+ * Search for players, set internal cache or return
1278
+ * count if $args['count'] is true
1279
+ *
1280
+ * @param array $args
1281
+ *
1282
+ * @return void|int
1283
+ */
1284
+ public function query_players( $args ) {
1285
+ $args = wp_parse_args( $args, array(
1286
+ 'author_id' => false,
1287
+ 'ids' => false,
1288
+ 'offset' => false,
1289
+ 'order' => false,
1290
+ 'order_by' => false,
1291
+ 'per_page' => false,
1292
+ 'search_by_video_ids' => false,
1293
+ 'select_fields' => false,
1294
+ 'count' => false
1295
+ ) );
1296
+
1297
+ $ids = array();
1298
+ if( is_array($args['ids']) ) {
1299
+ $ids = $args['ids'];
1300
+ } else if( $args['ids'] ) {
1301
+ $ids = explode( ',', $args['ids'] );
1302
+ }
1303
 
1304
+ $query_ids = array();
1305
+ foreach ( $ids as $id_key => $id_value ) {
1306
+ // check if this player is not cached yet
1307
+ if (!$this->isPlayerCached($id_value)) {
1308
+ $query_ids[ $id_key ] = (int) $id_value;
1309
  }
1310
+ }
1311
 
1312
+ // load multiple players via their IDs but a single query and return their values
1313
+ $select = 'p.*';
1314
+ if( !empty($args['select_fields']) ) {
1315
+ $select = 'p.id,'.esc_sql($args['select_fields']);
1316
+ }
1317
 
1318
+ if($args['count']) {
1319
+ $select = 'count(*) as row_count';
1320
+ }
 
 
 
1321
 
1322
+ $where = ' WHERE 1=1 ';
1323
+ if( count($query_ids) ) {
1324
+ $where .= ' AND p.id IN('. implode(',', $query_ids).') ';
1325
 
1326
+ // if we have multiple video IDs to load players for, let's prepare a like statement here
1327
+ } else if( is_array($args['search_by_video_ids']) ) {
1328
+ $where_like_part = array();
1329
+ foreach ($args['search_by_video_ids'] as $player_video_id) {
1330
+ $player_video_id = intval($player_video_id);
1331
 
1332
+ // TODO: What's the problem with FIND_IN_SET() ?
1333
+ $where_like_part[] = "(videos = \"$player_video_id\" OR videos LIKE \"%,$player_video_id\" OR videos LIKE \"$player_video_id,%\")";
1334
  }
1335
 
1336
+ $where .= ' AND (' . implode(' OR ', $where_like_part) . ') ';
1337
+ }
1338
+
1339
+ if( !empty( $args['author_id']) ) {
1340
+ $where .= ' AND author ='.intval($args['author_id']).' ';
1341
+ }
1342
+
1343
+ $order = '';
1344
+ if( !empty($args['order_by']) ) {
1345
+
1346
+ // Verify that each order by is valid
1347
+ $order_by_items = explode( ',', $args['order_by'] );
1348
+ $order_by_items = array_map( 'trim', $order_by_items );
1349
+
1350
+ foreach( $order_by_items AS $k => $v ) {
1351
+ if( !in_array($v, $this->valid_order_by ) ) {
1352
+ unset($order_by_items[$k]);
1353
  }
1354
  }
1355
+
1356
+ if( count($order_by_items) > 0 ) {
1357
+ $order = ' ORDER BY '.implode( ', ', array_map( 'esc_sql', $order_by_items ) );
1358
+ if( !empty($args['order']) ) {
1359
+ if( in_array($args['order'], array( 'asc', 'desc' ) ) ) {
1360
+ $order .= ' '.esc_sql($args['order']);
1361
+ }
1362
+ }
1363
  }
1364
+ }
1365
 
1366
+ $limit = '';
1367
+ if( $args['offset'] !== false && $args['per_page'] !== false ) {
1368
+ $limit = ' LIMIT '.intval($args['offset']).', '.intval($args['per_page']);
1369
+ }
1370
 
1371
+ $meta_counts_select = '';
1372
+ $meta_counts_join = '';
1373
+ if( is_admin() ) {
1374
+ $meta_table = FV_Player_Db_Video_Meta::get_db_table_name();
1375
+
1376
+ $meta_counts_select = ',
1377
+ count(subtitles.id) as subtitles_count,
1378
+ count(cues.id) as cues_count,
1379
+ count(chapters.id) as chapters_count,
1380
+ count(transcript.id) as transcript_count';
1381
+ $meta_counts_join = 'JOIN `'.FV_Player_Db_Video::get_db_table_name().'` AS v on FIND_IN_SET(v.id, p.videos)
1382
+ LEFT JOIN `'.$meta_table.'` AS subtitles ON v.id = subtitles.id_video AND subtitles.meta_key like "subtitles%"
1383
+ LEFT JOIN `'.$meta_table.'` AS cues ON v.id = cues.id_video AND cues.meta_key like "cues%"
1384
+ LEFT JOIN `'.$meta_table.'` AS chapters ON v.id = chapters.id_video AND chapters.meta_key = "chapters"
1385
+ LEFT JOIN `'.$meta_table.'` AS transcript ON v.id = transcript.id_video AND transcript.meta_key = "transcript"
1386
+ ';
1387
  }
1388
+
1389
+ global $wpdb;
1390
+
1391
+ if($args['count']) {
1392
+ $group_order = '';
1393
+ } else {
1394
+ $group_order = 'GROUP BY p.id'.$order.$limit;
1395
  }
1396
 
1397
+ $player_data = $wpdb->get_results('SELECT
1398
+ '.$select.$meta_counts_select.'
1399
+ FROM `'.FV_Player_Db_Player::get_db_table_name().'` AS p
1400
+ '.$meta_counts_join.$where.$group_order);
1401
+
1402
+
1403
+ if($args['count']) {
1404
+ return intval($player_data[0]->row_count);
1405
+ }
1406
+
1407
+ foreach( $player_data AS $db_record ) {
1408
+ // create a new video object and populate it with DB values
1409
+ $record_id = $db_record->id;
1410
+ // if we don't unset this, we'll get warnings
1411
+ unset($db_record->id);
1412
+
1413
+ $player_object = new FV_Player_Db_Player( null, get_object_vars( $db_record ), $this );
1414
+ $player_object->link2db( $record_id );
1415
+
1416
+ // cache this player in DB object
1417
+ $cache[$record_id] = $player_object;
1418
+ }
1419
+
1420
+ if(!empty($cache)) $this->setPlayersCache($cache);
1421
  }
1422
 
1423
  /**
1525
  ) {
1526
  die('Security check failed');
1527
  }
1528
+
1529
  if ( $id ) {
1530
  // first, load the player
1531
  $player = new FV_Player_Db_Player($id, array(), $this);
1532
  if ($player && $player->getIsValid()) {
1533
+ $cannot_edit_other_posts = !current_user_can('edit_others_posts');
1534
+ $author_id = get_current_user_id();
1535
+
1536
+ if( $cannot_edit_other_posts ) {
1537
+ if( $author_id !== $player->getAuthor() ) {
1538
+ die('You don\'t have permission to export this player.');
1539
+ }
1540
+ }
1541
+
1542
  $export_data = $player->export();
1543
 
1544
  // load player meta data
1680
  $player->setVideos(implode(',', $player_video_ids));
1681
 
1682
  // save player
1683
+ $id_player = $player->save(
1684
+ isset($data['meta']) ? $data['meta'] : array(),
1685
+ true
1686
+ );
 
 
 
 
 
 
1687
 
1688
  } catch (Exception $e) {
1689
  if (WP_DEBUG) {
1727
  // first, load the player
1728
  $player = new FV_Player_Db_Player($_POST['playerID'], array(), $this);
1729
  if ($player && $player->getIsValid()) {
1730
+ $cannot_edit_other_posts = !current_user_can('edit_others_posts');
1731
+ $author_id = get_current_user_id();
1732
+
1733
+ // check if user can delete player
1734
+ if( $cannot_edit_other_posts ) {
1735
+ if( $author_id !== $player->getAuthor() ) {
1736
+ die('You don\'t have permission to delete this player.');
1737
+ }
1738
+ }
1739
+
1740
  // remove the player
1741
  if ($player->delete()) {
1742
  echo 1;
1761
  */
1762
  public function clone_player() {
1763
  if (isset($_POST['playerID']) && is_numeric($_POST['playerID'])) {
1764
+ $cannot_edit_other_posts = !current_user_can('edit_others_posts');
1765
+ $author_id = get_current_user_id();
1766
+
1767
+ $player = new FV_Player_Db_Player( intval($_POST['playerID']), array(), $this );
1768
+
1769
+ if( $cannot_edit_other_posts ) {
1770
+ if( $author_id !== $player->getAuthor() ) {
1771
+ die('You don\'t have permission to clone this player.');
1772
+ }
1773
+ }
1774
+
1775
  $export_data = $this->export_player_data(null, false);
1776
 
1777
  // do not clone information about where the player is embeded
1849
  * into a dropdown in the front-end.
1850
  */
1851
  public function retrieve_all_players_for_dropdown() {
1852
+ $players = $this->getListPageData('date_created', 'desc', false, false);
1853
  $json_data = array();
1854
 
1855
  foreach ($players as $player) {
models/flowplayer-frontend.php CHANGED
@@ -467,7 +467,7 @@ class flowplayer_frontend extends flowplayer
467
  }
468
  $attributes['class'] .= ' no-svg is-paused '.$skin;
469
  $timeline_class = $this->_get_option(array($skin, 'design-timeline'));
470
- if( $bIsAudio && $timeline_class == 'fp-minimal' ) {
471
  $timeline_class = 'fp-slim';
472
  }
473
  $attributes['class'] .= ' '.$timeline_class.' '.$this->_get_option(array($skin, 'design-icons'));
@@ -480,8 +480,8 @@ class flowplayer_frontend extends flowplayer
480
  $attributes['class'] .= ' has-playlist has-playlist-'.$this->aCurArgs['liststyle'];
481
  }
482
 
483
-
484
- if( $autoplay != -1 ) {
485
  $attributes['data-fvautoplay'] = $autoplay;
486
  }
487
 
@@ -724,7 +724,7 @@ class flowplayer_frontend extends flowplayer
724
 
725
  if( !empty($this->aCurArgs['splash_text']) ) {
726
  $aSplashText = explode( ';', $this->aCurArgs['splash_text'] );
727
- $this->ret['html'] .= "<div class='fv-fp-splash-text'><span class='custom-play-button'>".$aSplashText[0]."</span></div>\n"; // needed for soap customizations of play button!
728
  }
729
 
730
  if( empty($this->aCurArgs['checker']) && !$this->_get_option('disable_videochecker') && current_user_can('manage_options') ) {
@@ -1243,15 +1243,19 @@ class flowplayer_frontend extends flowplayer
1243
 
1244
 
1245
  function get_title() {
 
 
1246
  if( !empty($this->aCurArgs['caption']) ) {
1247
- return trim($this->aCurArgs['caption']);
1248
  }
1249
 
1250
  if( !empty($this->aCurArgs['title']) ) {
1251
- return trim($this->aCurArgs['title']);
1252
  }
1253
-
1254
- return false;
 
 
1255
  }
1256
 
1257
 
467
  }
468
  $attributes['class'] .= ' no-svg is-paused '.$skin;
469
  $timeline_class = $this->_get_option(array($skin, 'design-timeline'));
470
+ if( $bIsAudio && ( $timeline_class == 'fp-minimal' || $timeline_class == 'fp-full' ) ) {
471
  $timeline_class = 'fp-slim';
472
  }
473
  $attributes['class'] .= ' '.$timeline_class.' '.$this->_get_option(array($skin, 'design-icons'));
480
  $attributes['class'] .= ' has-playlist has-playlist-'.$this->aCurArgs['liststyle'];
481
  }
482
 
483
+ // Only add the HTML code if autoplay is not disabled or if it's set to be disabled for the player
484
+ if( $autoplay != -1 || $autoplay == -1 && !empty($this->aCurArgs['autoplay']) && empty($this->aCurArgs['lightbox']) ) {
485
  $attributes['data-fvautoplay'] = $autoplay;
486
  }
487
 
724
 
725
  if( !empty($this->aCurArgs['splash_text']) ) {
726
  $aSplashText = explode( ';', $this->aCurArgs['splash_text'] );
727
+ $this->ret['html'] .= "<div class='fv-fp-splash-text'><span class='custom-play-button'>".flowplayer::filter_possible_html($aSplashText[0])."</span></div>\n"; // needed for soap customizations of play button!
728
  }
729
 
730
  if( empty($this->aCurArgs['checker']) && !$this->_get_option('disable_videochecker') && current_user_can('manage_options') ) {
1243
 
1244
 
1245
  function get_title() {
1246
+ $title = false;
1247
+
1248
  if( !empty($this->aCurArgs['caption']) ) {
1249
+ $title = $this->aCurArgs['caption'];
1250
  }
1251
 
1252
  if( !empty($this->aCurArgs['title']) ) {
1253
+ $title = $this->aCurArgs['title'];
1254
  }
1255
+
1256
+ $title = flowplayer::filter_possible_html($title);
1257
+ $title = trim($title);
1258
+ return $title;
1259
  }
1260
 
1261
 
models/flowplayer.php CHANGED
@@ -128,7 +128,7 @@ class flowplayer extends FV_Wordpress_Flowplayer_Plugin_Private {
128
 
129
  add_filter( 'fv_flowplayer_video_src', array( $this, 'get_amazon_secure') );
130
 
131
- add_filter( 'fv_player_item', array( $this, 'enable_cdn_rewrite'), 11 );
132
 
133
  add_filter( 'fv_flowplayer_splash', array( $this, 'get_amazon_secure') );
134
  add_filter( 'fv_flowplayer_playlist_splash', array( $this, 'get_amazon_secure') );
@@ -794,8 +794,13 @@ class flowplayer extends FV_Wordpress_Flowplayer_Plugin_Private {
794
  public function get_video_checker_media($mediaData , $src1 = false, $src2 = false, $rtmp = false) {
795
  global $FV_Player_Pro;
796
  $media = $mediaData['sources'];
 
 
 
 
 
797
 
798
- if( current_user_can('manage_options') && $this->ajax_count < 100 && !$this->_get_option('disable_videochecker') && ( $this->_get_option('video_checker_agreement') || $this->_get_option('key_automatic') ) ) {
799
  $this->ajax_count++;
800
 
801
  if( stripos($rtmp,'rtmp://') === false && $rtmp ) {
@@ -848,6 +853,8 @@ class flowplayer extends FV_Wordpress_Flowplayer_Plugin_Private {
848
 
849
  $aItem = isset($aPlayer['sources']) && isset($aPlayer['sources'][0]) ? $aPlayer['sources'][0] : false;
850
  $sListStyle = !empty($aArgs['liststyle']) ? $aArgs['liststyle'] : false;
 
 
851
 
852
  if( !$sItemCaption && $sListStyle == 'text' ) $sItemCaption = 'Video '.($index+1);
853
 
@@ -892,9 +899,9 @@ class flowplayer extends FV_Wordpress_Flowplayer_Plugin_Private {
892
  $sHTML .= "<div class='fvp-playlist-thumb-img'>";
893
  if( $sSplashImage ) {
894
  if( !( defined( 'DONOTROCKETOPTIMIZE' ) && DONOTROCKETOPTIMIZE ) && function_exists( 'get_rocket_option' ) && get_rocket_option( 'lazyload' ) ) {
895
- $sHTML .= "<img src='data:image/gif;base64,R0lGODdhAQABAPAAAP///wAAACwAAAAAAQABAEACAkQBADs=' data-lazy-src='$sSplashImage' />";
896
  } else {
897
- $sHTML .= "<img ".(get_query_var('fv_player_embed') ? "data-no-lazy='1'":"")." src='$sSplashImage' />";
898
  }
899
 
900
  } else {
@@ -1562,10 +1569,36 @@ class flowplayer extends FV_Wordpress_Flowplayer_Plugin_Private {
1562
 
1563
  return $item;
1564
  }
 
 
 
 
 
 
 
 
 
 
 
 
1565
 
1566
  public static function esc_caption( $caption ) {
1567
  return str_replace( array(';','[',']'), array('\;','(',')'), $caption );
1568
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1569
 
1570
 
1571
  function get_amazon_secure( $media ) {
@@ -1728,6 +1761,9 @@ class flowplayer extends FV_Wordpress_Flowplayer_Plugin_Private {
1728
  }
1729
 
1730
 
 
 
 
1731
  public static function get_duration_post( $post_id = false ) {
1732
  global $post, $fv_fp;
1733
  $post_id = ( $post_id ) ? $post_id : $post->ID;
@@ -1745,11 +1781,18 @@ class flowplayer extends FV_Wordpress_Flowplayer_Plugin_Private {
1745
  $content = false;
1746
  $objPost = get_post($post_id);
1747
  if( $aVideos = FV_Player_Checker::get_videos($objPost->ID) ) {
1748
- if( $sDuration = flowplayer::get_duration($post_id, $aVideos[0]) ) {
1749
- $content = $sDuration;
 
 
 
1750
  }
1751
  }
1752
 
 
 
 
 
1753
  return $content;
1754
  }
1755
 
128
 
129
  add_filter( 'fv_flowplayer_video_src', array( $this, 'get_amazon_secure') );
130
 
131
+ add_action( 'init', array( $this, 'enable_cdn_rewrite_maybe') );
132
 
133
  add_filter( 'fv_flowplayer_splash', array( $this, 'get_amazon_secure') );
134
  add_filter( 'fv_flowplayer_playlist_splash', array( $this, 'get_amazon_secure') );
794
  public function get_video_checker_media($mediaData , $src1 = false, $src2 = false, $rtmp = false) {
795
  global $FV_Player_Pro;
796
  $media = $mediaData['sources'];
797
+
798
+ static $enabled;
799
+ if( !isset($enabled) ) {
800
+ $enabled = current_user_can('manage_options') && !$this->_get_option('disable_videochecker') && ( $this->_get_option('video_checker_agreement') || $this->_get_option('key_automatic') );
801
+ }
802
 
803
+ if( $enabled && $this->ajax_count < 100 ) {
804
  $this->ajax_count++;
805
 
806
  if( stripos($rtmp,'rtmp://') === false && $rtmp ) {
853
 
854
  $aItem = isset($aPlayer['sources']) && isset($aPlayer['sources'][0]) ? $aPlayer['sources'][0] : false;
855
  $sListStyle = !empty($aArgs['liststyle']) ? $aArgs['liststyle'] : false;
856
+
857
+ $sItemCaption = flowplayer::filter_possible_html($sItemCaption);
858
 
859
  if( !$sItemCaption && $sListStyle == 'text' ) $sItemCaption = 'Video '.($index+1);
860
 
899
  $sHTML .= "<div class='fvp-playlist-thumb-img'>";
900
  if( $sSplashImage ) {
901
  if( !( defined( 'DONOTROCKETOPTIMIZE' ) && DONOTROCKETOPTIMIZE ) && function_exists( 'get_rocket_option' ) && get_rocket_option( 'lazyload' ) ) {
902
+ $sHTML .= "<img src='data:image/gif;base64,R0lGODdhAQABAPAAAP///wAAACwAAAAAAQABAEACAkQBADs=' data-lazy-src='".esc_attr($sSplashImage)."' />";
903
  } else {
904
+ $sHTML .= "<img ".(get_query_var('fv_player_embed') ? "data-no-lazy='1'":"")." src='".esc_attr($sSplashImage)."' />";
905
  }
906
 
907
  } else {
1569
 
1570
  return $item;
1571
  }
1572
+
1573
+ function enable_cdn_rewrite_maybe() {
1574
+ // Support WordPress CDN plugins - can slow down the PHP if you have hundreds of videos on a single page
1575
+ // We tried to check if the video is using the site domain before checking with the WordPress CDN plugins
1576
+ // But there is just no way around this - even that would be slow
1577
+ // So if you greatly care about peformance use:
1578
+ //
1579
+ // add_filter( 'fv_player_performance_disable_wp_cdn', '__return_true' );
1580
+ if( !apply_filters( 'fv_player_performance_disable_wp_cdn', false ) ) {
1581
+ add_filter( 'fv_player_item', array( $this, 'enable_cdn_rewrite'), 11 );
1582
+ }
1583
+ }
1584
 
1585
  public static function esc_caption( $caption ) {
1586
  return str_replace( array(';','[',']'), array('\;','(',')'), $caption );
1587
  }
1588
+
1589
+ /*
1590
+ * Use the heavy-duty WordPress HTML filtering if the value looks like it might be HTML
1591
+ *
1592
+ * @param string $content
1593
+ *
1594
+ * @return string Filtered string
1595
+ */
1596
+ public static function filter_possible_html( $content ) {
1597
+ if( stripos($content, '<') !== false || stripos($content, '>') !== false ) {
1598
+ $content = wp_kses( $content, 'post' );
1599
+ }
1600
+ return $content;
1601
+ }
1602
 
1603
 
1604
  function get_amazon_secure( $media ) {
1761
  }
1762
 
1763
 
1764
+ /*
1765
+ * Get duration of the longets video in the post
1766
+ */
1767
  public static function get_duration_post( $post_id = false ) {
1768
  global $post, $fv_fp;
1769
  $post_id = ( $post_id ) ? $post_id : $post->ID;
1781
  $content = false;
1782
  $objPost = get_post($post_id);
1783
  if( $aVideos = FV_Player_Checker::get_videos($objPost->ID) ) {
1784
+ foreach( $aVideos AS $video ) {
1785
+ $tDuration = flowplayer::get_duration($post_id, $video, true );
1786
+ if( !$content || $tDuration > $content ) {
1787
+ $content = $tDuration;
1788
+ }
1789
  }
1790
  }
1791
 
1792
+ if( $content ) {
1793
+ $content = flowplayer::format_hms($content);
1794
+ }
1795
+
1796
  return $content;
1797
  }
1798
 
models/learndash.php CHANGED
@@ -175,6 +175,20 @@ class FV_Player_Learndash_LMS {
175
  // Adjust the Video URL stored by LearnDash
176
  $meta = get_post_meta( $post_id, $meta_key, true );
177
  if( $meta ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  $backup = get_post_meta( $post_id, $backup_key, true );
179
  if( $lesson_use_fvplayer_video ) {
180
  if( !$backup ) {
175
  // Adjust the Video URL stored by LearnDash
176
  $meta = get_post_meta( $post_id, $meta_key, true );
177
  if( $meta ) {
178
+
179
+ // If we detect [fvplayer] shortcode was used as Video URL we enable FV Player
180
+ if( stripos($meta[$video_url_key],'[fvplayer ') !== false ) {
181
+
182
+ // If the FV Player is not already in
183
+ // ...or if Use FV Player is not on
184
+ $objVideos = new FV_Player_Custom_Videos( array('id' => $post_id, 'meta' => 'lesson_fv_player', 'type' => 'post' ) );
185
+ if( !$objVideos->have_videos() || !$lesson_use_fvplayer_video ) {
186
+ $lesson_use_fvplayer_video = true;
187
+ update_post_meta( $post_id, 'lesson_use_fvplayer_video', 'on' );
188
+ update_post_meta( $post_id, 'lesson_fv_player', $meta[$video_url_key] );
189
+ }
190
+ }
191
+
192
  $backup = get_post_meta( $post_id, $backup_key, true );
193
  if( $lesson_use_fvplayer_video ) {
194
  if( !$backup ) {
models/lightbox.php CHANGED
@@ -147,7 +147,7 @@ class FV_Player_lightbox {
147
  /*
148
  * Controls the stylesheet and script loading
149
  */
150
- function enqueue() {
151
  $this->bLoad = true;
152
  }
153
 
147
  /*
148
  * Controls the stylesheet and script loading
149
  */
150
+ public function enqueue() {
151
  $this->bLoad = true;
152
  }
153
 
models/list-table.php CHANGED
@@ -278,7 +278,7 @@ class FV_Player_List_Table extends WP_List_Table {
278
  $value = $player->date_created > 0 ? "<abbr title='$player->date_created'>".date('Y/m/d',strtotime($player->date_created))."</abbr>" : false;
279
  break;
280
  case 'player_name' :
281
- $value = "<a href='#' class='fv-player-edit' data-player_id='{$id}'>".$player->player_name."</a>\n";
282
  $value .= "<div class='row-actions'>";
283
  $value .= "<a href='#' class='fv-player-edit' data-player_id='{$id}'>Edit</a> | ";
284
  $value .= "<a href='#' class='fv-player-export' data-player_id='{$id}' data-nonce='".wp_create_nonce('fv-player-db-export-'.$id)."'>Export</a> | ";
@@ -335,19 +335,22 @@ class FV_Player_List_Table extends WP_List_Table {
335
  }
336
 
337
  public function get_result_counts() {
338
- $this->total_items = FV_Player_Db_Player::getTotalPlayersCount();
 
339
  }
340
 
341
  public function get_data() {
342
  $current = !empty($_GET['paged']) ? intval($_GET['paged']) : 1;
343
  $order = !empty($_GET['order']) ? esc_sql($_GET['order']) : 'desc';
344
- $order_by = !empty($_GET['orderby']) ? esc_sql($_GET['orderby']) : 'p.id';
345
  $single_id = !empty($_GET['id']) ? esc_sql($_GET['id']) : null;
346
- $search = !empty($_GET['s']) ? $_GET['s'] : null;
347
 
348
  $per_page = $this->args['per_page'];
349
  $offset = ( $current - 1 ) * $per_page;
350
- return FV_Player_Db::getListPageData($order_by, $order, $offset, $per_page, $single_id, $search);
 
 
351
  }
352
 
353
  public function prepare_items() {
278
  $value = $player->date_created > 0 ? "<abbr title='$player->date_created'>".date('Y/m/d',strtotime($player->date_created))."</abbr>" : false;
279
  break;
280
  case 'player_name' :
281
+ $value = "<a href='#' class='fv-player-edit' data-player_id='{$id}'>".flowplayer::filter_possible_html($player->player_name)."</a>\n";
282
  $value .= "<div class='row-actions'>";
283
  $value .= "<a href='#' class='fv-player-edit' data-player_id='{$id}'>Edit</a> | ";
284
  $value .= "<a href='#' class='fv-player-export' data-player_id='{$id}' data-nonce='".wp_create_nonce('fv-player-db-export-'.$id)."'>Export</a> | ";
335
  }
336
 
337
  public function get_result_counts() {
338
+ global $FV_Player_Db;
339
+ $this->total_items = $FV_Player_Db->getListPageCount();
340
  }
341
 
342
  public function get_data() {
343
  $current = !empty($_GET['paged']) ? intval($_GET['paged']) : 1;
344
  $order = !empty($_GET['order']) ? esc_sql($_GET['order']) : 'desc';
345
+ $order_by = !empty($_GET['orderby']) ? esc_sql($_GET['orderby']) : 'date_created';
346
  $single_id = !empty($_GET['id']) ? esc_sql($_GET['id']) : null;
347
+ $search = !empty($_GET['s']) ? trim($_GET['s']) : null;
348
 
349
  $per_page = $this->args['per_page'];
350
  $offset = ( $current - 1 ) * $per_page;
351
+
352
+ global $FV_Player_Db;
353
+ return $FV_Player_Db->getListPageData($order_by, $order, $offset, $per_page, $single_id, $search);
354
  }
355
 
356
  public function prepare_items() {
models/player-position-save.php CHANGED
@@ -35,6 +35,7 @@ class FV_Player_Position_Save {
35
  isset($aItem['sources'][0])
36
  ) {
37
 
 
38
  $try = array();
39
  if( $fv_fp->current_player() ) {
40
  $aVideos = $fv_fp->current_player()->getVideos();
@@ -42,6 +43,7 @@ class FV_Player_Position_Save {
42
  $try[] = $aVideos[$index]->getId();
43
  }
44
  }
 
45
  $try[] = $this->get_extensionless_file_name($aItem['sources'][0]['src']);
46
 
47
  foreach( $try AS $name ) {
@@ -50,6 +52,13 @@ class FV_Player_Position_Save {
50
  break;
51
  }
52
  }
 
 
 
 
 
 
 
53
 
54
  foreach( $try AS $name ) {
55
  if( $metaPosition = get_user_meta( get_current_user_id(), 'fv_wp_flowplayer_saw_' . $name, true ) ) {
@@ -86,23 +95,45 @@ class FV_Player_Position_Save {
86
  if ( is_user_logged_in() ) {
87
  $uid = get_current_user_id();
88
  if (isset($_POST['videoTimes']) && ($times = $_POST['videoTimes']) && count($times)) {
89
-
90
  foreach ($times as $record) {
91
  $name = $this->get_extensionless_file_name($record['name']);
92
  if( intval($record['position']) == 0 ) {
93
  delete_user_meta($uid, 'fv_wp_flowplayer_position_'.$name );
94
  } else {
 
 
 
 
 
 
95
  update_user_meta($uid, 'fv_wp_flowplayer_position_'.$name, $record['position']);
 
 
 
 
 
 
 
 
 
 
 
 
96
  }
97
 
 
98
  if( !empty($record['saw']) && $record['saw'] == true ) {
99
  update_user_meta($uid, 'fv_wp_flowplayer_saw_'.$name, true);
 
100
  }
101
  }
102
 
 
103
  if( !empty($_POST['sawVideo']) && is_array($_POST['sawVideo']) ) {
104
  foreach ($_POST['sawVideo'] as $record) {
105
  update_user_meta($uid, 'fv_wp_flowplayer_saw_'.$this->get_extensionless_file_name($record['name']), true);
 
106
  }
107
  }
108
 
@@ -145,11 +176,14 @@ class FV_Player_Position_Save {
145
  if( $player_id ) { // add id to data item if db player
146
  $attributes['data-player-id'] = $player_id;
147
 
148
- $metaItem = get_user_meta( get_current_user_id(), 'fv_wp_flowplayer_player_playlist_' . $player_id, true );
 
 
149
 
150
- if ( $metaItem >= 0 ) {
151
- // playlist item restore
152
- $attributes['data-playlist_start'] = intval($metaItem) + 1; // playlist-start-position module starts from 0
 
153
  }
154
  }
155
  }
35
  isset($aItem['sources'][0])
36
  ) {
37
 
38
+ // Try with the video ID first
39
  $try = array();
40
  if( $fv_fp->current_player() ) {
41
  $aVideos = $fv_fp->current_player()->getVideos();
43
  $try[] = $aVideos[$index]->getId();
44
  }
45
  }
46
+ // ...then try with the video filename
47
  $try[] = $this->get_extensionless_file_name($aItem['sources'][0]['src']);
48
 
49
  foreach( $try AS $name ) {
52
  break;
53
  }
54
  }
55
+
56
+ foreach( $try AS $name ) {
57
+ if( $metaPosition = get_user_meta( get_current_user_id(), 'fv_wp_flowplayer_top_position_' . $name, true ) ) {
58
+ $aItem['sources'][0]['top_position'] = intval($metaPosition);
59
+ break;
60
+ }
61
+ }
62
 
63
  foreach( $try AS $name ) {
64
  if( $metaPosition = get_user_meta( get_current_user_id(), 'fv_wp_flowplayer_saw_' . $name, true ) ) {
95
  if ( is_user_logged_in() ) {
96
  $uid = get_current_user_id();
97
  if (isset($_POST['videoTimes']) && ($times = $_POST['videoTimes']) && count($times)) {
98
+ var_dump($times);
99
  foreach ($times as $record) {
100
  $name = $this->get_extensionless_file_name($record['name']);
101
  if( intval($record['position']) == 0 ) {
102
  delete_user_meta($uid, 'fv_wp_flowplayer_position_'.$name );
103
  } else {
104
+ $position = floatval($record['position']);
105
+ $top_position = floatval($record['top_position']);
106
+ $previous_position = floatval( get_user_meta( $uid, 'fv_wp_flowplayer_position_'.$name, true ) );
107
+ $previous_top_position = floatval( get_user_meta( $uid, 'fv_wp_flowplayer_top_position_'.$name, true ) );
108
+ $saw = get_user_meta( $uid, 'fv_wp_flowplayer_saw_'.$name, true );
109
+
110
  update_user_meta($uid, 'fv_wp_flowplayer_position_'.$name, $record['position']);
111
+
112
+ // Store the top position if user didn't see the full video
113
+ // and if it's the same or bigger than what it was before
114
+ // and if it's bigger than the last position
115
+ $max = max( array( $previous_top_position, $previous_position, $position, $top_position ) );
116
+ if( !$saw && $max >= $previous_top_position && $max > $position ) {
117
+ update_user_meta($uid, 'fv_wp_flowplayer_top_position_'.$name, $max);
118
+
119
+ // Otherwise get rid of it
120
+ } else {
121
+ delete_user_meta($uid, 'fv_wp_flowplayer_top_position_'.$name);
122
+ }
123
  }
124
 
125
+ // Did the user saw the full video?
126
  if( !empty($record['saw']) && $record['saw'] == true ) {
127
  update_user_meta($uid, 'fv_wp_flowplayer_saw_'.$name, true);
128
+ delete_user_meta($uid, 'fv_wp_flowplayer_top_position_'.$name );
129
  }
130
  }
131
 
132
+ // What are the videos which user saw in full length?
133
  if( !empty($_POST['sawVideo']) && is_array($_POST['sawVideo']) ) {
134
  foreach ($_POST['sawVideo'] as $record) {
135
  update_user_meta($uid, 'fv_wp_flowplayer_saw_'.$this->get_extensionless_file_name($record['name']), true);
136
+ delete_user_meta($uid, 'fv_wp_flowplayer_top_position_'.$name );
137
  }
138
  }
139
 
176
  if( $player_id ) { // add id to data item if db player
177
  $attributes['data-player-id'] = $player_id;
178
 
179
+ $user_id = get_current_user_id();
180
+ if( $user_id ) {
181
+ $metaItem = get_user_meta( $user_id, 'fv_wp_flowplayer_player_playlist_' . $player_id, true );
182
 
183
+ if ( $metaItem >= 0 ) {
184
+ // playlist item restore
185
+ $attributes['data-playlist_start'] = intval($metaItem) + 1; // playlist-start-position module starts from 0
186
+ }
187
  }
188
  }
189
  }
models/video-encoder/video-encoder.php CHANGED
@@ -10,12 +10,15 @@ abstract class FV_Player_Video_Encoder {
10
  // examples: Coconut, Bunny Stream ...
11
  $instance = null, // self-explanatory
12
  $admin_page = false, // will be set to a real admin submenu page object once created
13
- $browser_inc_file = ''; // the full inclusion path for this Encoder's browser PHP backend file, so we can include_once() it
 
14
 
15
  // variables to override or access from outside of the base class
16
  protected
17
  $version = 'latest',
18
- $license_key = false,
 
 
19
  $table_name = 'fv_player_encoding_jobs'; // table in which encoding jobs are stored
20
 
21
  public function _get_instance() {
@@ -30,7 +33,7 @@ abstract class FV_Player_Video_Encoder {
30
  return $this->table_name;
31
  }
32
 
33
- protected function __construct( $encoder_id, $encoder_name, $encoder_wp_url_slug, $browser_inc_file ) {
34
  global $wpdb;
35
 
36
  if ( !$encoder_id ) {
@@ -45,10 +48,6 @@ abstract class FV_Player_Video_Encoder {
45
  throw new Exception('Extending encoder class did not provide an encoder URL slug!');
46
  }
47
 
48
- if ( !$browser_inc_file ) {
49
- throw new Exception('Extending encoder class did not provide a browser backend PHP file name!');
50
- }
51
-
52
  $this->encoder_id = $encoder_id;
53
  $this->encoder_name = $encoder_name;
54
  $this->encoder_wp_url_slug = $encoder_wp_url_slug;
@@ -56,6 +55,7 @@ abstract class FV_Player_Video_Encoder {
56
  // table names always start on WP prefix, so add that here for our table name here
57
  $this->table_name = $wpdb->prefix . $this->table_name;
58
  $this->browser_inc_file = $browser_inc_file;
 
59
 
60
  add_action('init', array( $this, 'email_notification' ), 7 );
61
 
@@ -339,6 +339,10 @@ abstract class FV_Player_Video_Encoder {
339
  }
340
  }
341
 
 
 
 
 
342
  $target = $this->util__sanitize_target($target);
343
 
344
  // check for a valid source URL
@@ -394,6 +398,10 @@ abstract class FV_Player_Video_Encoder {
394
  $job['trailer'] = $trailer;
395
  }
396
 
 
 
 
 
397
  // create a new job
398
  $id = $this->job_create( $job );
399
  $show = array( $id );
@@ -401,7 +409,7 @@ abstract class FV_Player_Video_Encoder {
401
  // submit the job to the Encoder service
402
  $result = $this->job_submit($id);
403
 
404
- if( defined('DOING_AJAX') ) {
405
  require_once dirname( __FILE__ ) . '/class.fv-player-encoder-list-table.php';
406
 
407
  ob_start();
@@ -423,7 +431,9 @@ abstract class FV_Player_Video_Encoder {
423
  function init_browser() {
424
  // it should not show when picking the media file in dashboard
425
  //if( empty( $_GET['page'] ) || strcmp( $_GET['page'], $this->encoder_wp_url_slug ) != 0 ) {
 
426
  include_once( $this->browser_inc_file );
 
427
  //}
428
  }
429
 
@@ -505,7 +515,11 @@ abstract class FV_Player_Video_Encoder {
505
  if ( $check_result ) {
506
  $check = $check_result;
507
  } else if ( $fv_fp->current_video() ) {
 
508
  $check = $this->job_check( (int) substr( $fv_fp->current_video()->getSrc(), strlen( $this->encoder_id . '_processing_' ) ) );
 
 
 
509
  } else {
510
  user_error('Could not retrieve JOB check for encoder ' . $this->encoder_name . ', job ID: ' . $job_id . ', defaulted back to input value: ' . print_r( $check_result, true ), E_USER_WARNING );
511
  return $check_result;
@@ -590,18 +604,20 @@ abstract class FV_Player_Video_Encoder {
590
  * @return ID Job ID
591
  */
592
  public function job_create( $args ) {
593
- global $wpdb;
594
- global $fv_fp;
595
 
596
  $args = wp_parse_args( $args, array(
597
  'encryption' => false,
598
  'trailer' => false,
599
- 'video_id' => false
600
  ) );
601
 
 
 
602
  // first we instert the table row with basic data and remember the row ID
603
  $wpdb->insert( $this->table_name, array(
604
  'date_created' => date("Y-m-d H:i:s"),
 
605
  'source' => $args['source'],
606
  'target' => $args['target'],
607
  'type' => $this->encoder_id,
@@ -609,9 +625,11 @@ abstract class FV_Player_Video_Encoder {
609
  'status' => 'created',
610
  'output' => $this->prepare_job_output_column_value(),
611
  'args' => '',
612
- 'author' => get_current_user_id()
 
613
  ), array(
614
  '%s',
 
615
  '%s',
616
  '%s',
617
  '%s',
@@ -619,6 +637,7 @@ abstract class FV_Player_Video_Encoder {
619
  '%s',
620
  '%s',
621
  '%s',
 
622
  '%d'
623
  ));
624
 
10
  // examples: Coconut, Bunny Stream ...
11
  $instance = null, // self-explanatory
12
  $admin_page = false, // will be set to a real admin submenu page object once created
13
+ $browser_inc_file = '', // the full inclusion path for this Encoder's browser PHP backend file, so we can include_once() it
14
+ $use_wp_list_table; // allow descendants to decide if use wp list table
15
 
16
  // variables to override or access from outside of the base class
17
  protected
18
  $version = 'latest',
19
+ $license_key = false;
20
+
21
+ public
22
  $table_name = 'fv_player_encoding_jobs'; // table in which encoding jobs are stored
23
 
24
  public function _get_instance() {
33
  return $this->table_name;
34
  }
35
 
36
+ protected function __construct( $encoder_id, $encoder_name, $encoder_wp_url_slug, $browser_inc_file = '', $use_wp_list_table = true ) {
37
  global $wpdb;
38
 
39
  if ( !$encoder_id ) {
48
  throw new Exception('Extending encoder class did not provide an encoder URL slug!');
49
  }
50
 
 
 
 
 
51
  $this->encoder_id = $encoder_id;
52
  $this->encoder_name = $encoder_name;
53
  $this->encoder_wp_url_slug = $encoder_wp_url_slug;
55
  // table names always start on WP prefix, so add that here for our table name here
56
  $this->table_name = $wpdb->prefix . $this->table_name;
57
  $this->browser_inc_file = $browser_inc_file;
58
+ $this->use_wp_list_table = $use_wp_list_table;
59
 
60
  add_action('init', array( $this, 'email_notification' ), 7 );
61
 
339
  }
340
  }
341
 
342
+ if( isset( $_POST['id_video'] ) ) {
343
+ $id_video = intval( $_POST['id_video'] );
344
+ }
345
+
346
  $target = $this->util__sanitize_target($target);
347
 
348
  // check for a valid source URL
398
  $job['trailer'] = $trailer;
399
  }
400
 
401
+ if( isset( $id_video ) ) {
402
+ $job['id_video'] = $id_video;
403
+ }
404
+
405
  // create a new job
406
  $id = $this->job_create( $job );
407
  $show = array( $id );
409
  // submit the job to the Encoder service
410
  $result = $this->job_submit($id);
411
 
412
+ if( defined('DOING_AJAX') && $this->use_wp_list_table ) {
413
  require_once dirname( __FILE__ ) . '/class.fv-player-encoder-list-table.php';
414
 
415
  ob_start();
431
  function init_browser() {
432
  // it should not show when picking the media file in dashboard
433
  //if( empty( $_GET['page'] ) || strcmp( $_GET['page'], $this->encoder_wp_url_slug ) != 0 ) {
434
+ if( !empty( $this->browser_inc_file ) ) {
435
  include_once( $this->browser_inc_file );
436
+ }
437
  //}
438
  }
439
 
515
  if ( $check_result ) {
516
  $check = $check_result;
517
  } else if ( $fv_fp->current_video() ) {
518
+ if ( !$job_id ) {
519
  $check = $this->job_check( (int) substr( $fv_fp->current_video()->getSrc(), strlen( $this->encoder_id . '_processing_' ) ) );
520
+ } else {
521
+ $check = $this->job_check( (int) $job_id );
522
+ }
523
  } else {
524
  user_error('Could not retrieve JOB check for encoder ' . $this->encoder_name . ', job ID: ' . $job_id . ', defaulted back to input value: ' . print_r( $check_result, true ), E_USER_WARNING );
525
  return $check_result;
604
  * @return ID Job ID
605
  */
606
  public function job_create( $args ) {
607
+ global $wpdb, $fv_fp;
 
608
 
609
  $args = wp_parse_args( $args, array(
610
  'encryption' => false,
611
  'trailer' => false,
612
+ 'id_video' => false
613
  ) );
614
 
615
+ $video_ids = explode( ',', strval($args['id_video']) );
616
+
617
  // first we instert the table row with basic data and remember the row ID
618
  $wpdb->insert( $this->table_name, array(
619
  'date_created' => date("Y-m-d H:i:s"),
620
+ 'id_video' => $args['id_video'],
621
  'source' => $args['source'],
622
  'target' => $args['target'],
623
  'type' => $this->encoder_id,
625
  'status' => 'created',
626
  'output' => $this->prepare_job_output_column_value(),
627
  'args' => '',
628
+ 'author' => get_current_user_id(),
629
+ 'id_video' => $video_ids[0]
630
  ), array(
631
  '%s',
632
+ '%d',
633
  '%s',
634
  '%s',
635
  '%s',
637
  '%s',
638
  '%s',
639
  '%s',
640
+ '%d',
641
  '%d'
642
  ));
643
 
readme.txt CHANGED
@@ -359,6 +359,39 @@ Thank you for being part of the HMTL 5 mobile video revolution!
359
 
360
  == Changelog ==
361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  = 7.5.15.727 - 2022/01/27 =
363
 
364
  * HLS.js - upgrade to 1.1.4 to fix playback on Apple Silicon M1 computers
359
 
360
  == Changelog ==
361
 
362
+ = 7.5.21.727 - 2022/04/07 =
363
+
364
+ * Bugfix - Position saving - issues with position restore when multiple players on the page
365
+ * Bugfix - CSS - ensure the controlbar fonts load before video starts playing
366
+ * Bugfix - LearnDash LMS support - fix FV Player Pro video ads to not affect lesson completion button
367
+
368
+ = 7.5.20.727 - 2022/03/25 =
369
+
370
+ * Urgent Bugfix - video splash screens not disappearing for non-Pro users
371
+
372
+ = 7.5.19.727 - 2022/03/24 =
373
+
374
+ * Security - player editing permission checks for Contributors and Authors
375
+ * Security - XSS fix - users with the Contributor role (or above) were able to insert rudimentary JavaScript into FV Player. Thanks to m0ze (Patchstack) for the report!
376
+ * Autoplay - only remove splash once video really plays to prevent empty black video from showing
377
+ * LearnDash LMS support - fix display issues with playlist
378
+ * Bugfix - Position saving - skip playlist position restore for YouTube playlist - for now
379
+ * Bugfix - Position saving - fix for invalid player index for non-logged in users
380
+
381
+ = 7.5.18.727 - 2022/03/18 =
382
+
383
+ * Security - fix for SQL injection vulnerability when saving player in editor - for Author user level and above. Thanks to Tien Nguyen Anh for the report!
384
+ * Elementor - Bring back the FV Player into Elementor Elements search
385
+ * Media Library - optimized images loading
386
+ * Shortcode to database conversion tool fixes
387
+ * wp-admin -> FV Player - allow search by player ID
388
+ * Bugfix - bad values coming from the background video duration scanner
389
+ * Bugfix - JavaScript compatibility fixes
390
+ * Bugfix - Picture button stopped working
391
+ * Bugfix - Sticky player - fix when closing sticky mode
392
+ * Bugfix - Sticky player - fix when scrolling too fast
393
+ * Bugfix - Volume restoration not working if default volume set to zero
394
+
395
  = 7.5.15.727 - 2022/01/27 =
396
 
397
  * HLS.js - upgrade to 1.1.4 to fix playback on Apple Silicon M1 computers
uninstall.php CHANGED
@@ -64,6 +64,9 @@ if( isset($options['remove_all_data']) && filter_var($options['remove_all_data']
64
 
65
  $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'fv\_player\_%'" );
66
  $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'fv-player-%'" );
 
 
 
67
 
68
  // delete plugin created folders
69
  if ( WP_Filesystem() ) {
64
 
65
  $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'fv\_player\_%'" );
66
  $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'fv-player-%'" );
67
+
68
+ $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key LIKE 'fv_wp_flowplayer_%'" );
69
+ $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN( 'closedpostboxes_fv_flowplayer_settings', 'metaboxhidden_fv_flowplayer_settings' ) " );
70
 
71
  // delete plugin created folders
72
  if ( WP_Filesystem() ) {
view/admin.php CHANGED
@@ -1855,19 +1855,19 @@ add_meta_box( 'fv_flowplayer_usage', __('Usage', 'fv-wordpress-flowplayer'), 'fv
1855
  </h2>
1856
  </div>
1857
 
1858
- <div id="dashboard-widgets" class="metabox-holder fv-metabox-holder columns-1">
1859
  <?php foreach($fv_player_aSettingsTabs as $key => $val):?>
1860
- <div id='postbox-container-<?php echo $val['hash']; ?>' class='postbox-container'<?php if( $key > 0 ) : ?> style=""<?php endif; ?>>
1861
- <?php
1862
- do_meta_boxes($val['id'], 'normal', false );
1863
- wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
1864
- wp_nonce_field( 'meta-box-order-nonce', 'meta-box-order-nonce', false );
1865
- ?>
1866
- </div>
1867
  <?php endforeach;?>
1868
  <div style="clear: both"></div>
1869
- </div>
1870
- <?php wp_nonce_field( 'fv_flowplayer_settings_nonce', 'fv_flowplayer_settings_nonce' ); ?>
 
 
 
 
1871
  </form>
1872
 
1873
  </div>
@@ -1937,20 +1937,22 @@ add_meta_box( 'fv_flowplayer_usage', __('Usage', 'fv-wordpress-flowplayer'), 'fv
1937
 
1938
 
1939
  <script type="text/javascript">
1940
- //<![CDATA[
1941
- jQuery(document).one( 'ready', function() {
 
 
1942
  // close postboxes that should be closed
1943
  jQuery('.if-js-closed').removeClass('if-js-closed').addClass('closed');
1944
  // postboxes setup
1945
  postboxes.add_postbox_toggles('fv_flowplayer_settings');
1946
-
1947
  jQuery('.fv_wp_flowplayer_activate_extension').on('click', function() { // todo: block multiple clicks
1948
  var button = jQuery(this);
1949
  button.siblings('img').eq(0).show();
1950
-
1951
  jQuery.post( ajaxurl, { action: 'fv_wp_flowplayer_activate_extension', nonce: '<?php echo wp_create_nonce( 'fv_wp_flowplayer_activate_extension' ); ?>', plugin: jQuery(this).attr("data-plugin") }, function( response ) {
1952
  button.siblings('img').eq(0).hide();
1953
-
1954
  var obj;
1955
  try {
1956
  response = response.replace( /[\s\S]*<FVFLOWPLAYER>/, '' );
@@ -2035,7 +2037,7 @@ add_meta_box( 'fv_flowplayer_usage', __('Usage', 'fv-wordpress-flowplayer'), 'fv
2035
 
2036
  cb_js_optimize.prop('readonly', cb_js_everywhere.prop('checked') );
2037
  }
2038
- cb_js_everywhere.click( check_js_everywhere );
2039
  check_js_everywhere();
2040
 
2041
  function check_js_optimize( was_clicked ) {
@@ -2046,22 +2048,23 @@ add_meta_box( 'fv_flowplayer_usage', __('Usage', 'fv-wordpress-flowplayer'), 'fv
2046
 
2047
  cb_js_everywhere.prop('readonly', cb_js_optimize.prop('checked') );
2048
  }
2049
- cb_js_optimize.click( check_js_optimize );
2050
  check_js_optimize();
 
 
2051
  });
2052
- //]]>
2053
  </script>
2054
 
2055
  <script>
2056
- /* TABS */
2057
- jQuery(document).ready(function(){
2058
  jQuery('#fv_player_js_warning').hide();
2059
-
2060
  var anchor = window.location.hash.substring(1);
2061
  if( !anchor || !anchor.match(/tab_/) ) {
2062
  anchor = 'postbox-container-tab_basic';
2063
  }
2064
-
2065
  jQuery('#fv_flowplayer_admin_tabs .nav-tab').removeClass('nav-tab-active');
2066
  jQuery('[href=\\#'+anchor+']').addClass('nav-tab-active');
2067
  jQuery('#dashboard-widgets .postbox-container').hide();
1855
  </h2>
1856
  </div>
1857
 
1858
+ <div id="dashboard-widgets" class="metabox-holder fv-metabox-holder columns-1">
1859
  <?php foreach($fv_player_aSettingsTabs as $key => $val):?>
1860
+ <div id='postbox-container-<?php echo $val['hash']; ?>' class='postbox-container'<?php if( $key > 0 ) : ?> style=""<?php endif; ?>>
1861
+ <?php do_meta_boxes($val['id'], 'normal', false ); ?>
1862
+ </div>
 
 
 
 
1863
  <?php endforeach;?>
1864
  <div style="clear: both"></div>
1865
+ </div>
1866
+ <?php
1867
+ wp_nonce_field( 'fv_flowplayer_settings_nonce', 'fv_flowplayer_settings_nonce' );
1868
+ wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
1869
+ wp_nonce_field( 'meta-box-order-nonce', 'meta-box-order-nonce', false );
1870
+ ?>
1871
  </form>
1872
 
1873
  </div>
1937
 
1938
 
1939
  <script type="text/javascript">
1940
+ console.log( 'FV Player Settings screen loading...');
1941
+ jQuery(window).one( 'load', function() {
1942
+ console.log( 'FV Player Settings screen initializing settings boxes...');
1943
+
1944
  // close postboxes that should be closed
1945
  jQuery('.if-js-closed').removeClass('if-js-closed').addClass('closed');
1946
  // postboxes setup
1947
  postboxes.add_postbox_toggles('fv_flowplayer_settings');
1948
+
1949
  jQuery('.fv_wp_flowplayer_activate_extension').on('click', function() { // todo: block multiple clicks
1950
  var button = jQuery(this);
1951
  button.siblings('img').eq(0).show();
1952
+
1953
  jQuery.post( ajaxurl, { action: 'fv_wp_flowplayer_activate_extension', nonce: '<?php echo wp_create_nonce( 'fv_wp_flowplayer_activate_extension' ); ?>', plugin: jQuery(this).attr("data-plugin") }, function( response ) {
1954
  button.siblings('img').eq(0).hide();
1955
+
1956
  var obj;
1957
  try {
1958
  response = response.replace( /[\s\S]*<FVFLOWPLAYER>/, '' );
2037
 
2038
  cb_js_optimize.prop('readonly', cb_js_everywhere.prop('checked') );
2039
  }
2040
+ cb_js_everywhere.on( 'click', check_js_everywhere );
2041
  check_js_everywhere();
2042
 
2043
  function check_js_optimize( was_clicked ) {
2048
 
2049
  cb_js_everywhere.prop('readonly', cb_js_optimize.prop('checked') );
2050
  }
2051
+ cb_js_optimize.on( 'click', check_js_optimize );
2052
  check_js_optimize();
2053
+
2054
+ console.log( 'FV Player Settings screen initializing finished.');
2055
  });
 
2056
  </script>
2057
 
2058
  <script>
2059
+ /* TABS */
2060
+ jQuery(window).one( 'load', function() {
2061
  jQuery('#fv_player_js_warning').hide();
2062
+
2063
  var anchor = window.location.hash.substring(1);
2064
  if( !anchor || !anchor.match(/tab_/) ) {
2065
  anchor = 'postbox-container-tab_basic';
2066
  }
2067
+
2068
  jQuery('#fv_flowplayer_admin_tabs .nav-tab').removeClass('nav-tab-active');
2069
  jQuery('[href=\\#'+anchor+']').addClass('nav-tab-active');
2070
  jQuery('#dashboard-widgets .postbox-container').hide();