1/*! 2 * jquery-timepicker v1.11.14 - A jQuery timepicker plugin inspired by Google Calendar. It supports both mouse and keyboard navigation. 3 * Copyright (c) 2018 Jon Thornton - http://jonthornton.github.com/jquery-timepicker/ 4 * License: MIT 5 */ 6 7!function(a){"object"==typeof exports&&exports&&"object"==typeof module&&module&&module.exports===exports?a(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){function b(a){var b=a[0];return b.offsetWidth>0&&b.offsetHeight>0}function c(b){if(b.minTime&&(b.minTime=t(b.minTime)),b.maxTime&&(b.maxTime=t(b.maxTime)),b.durationTime&&"function"!=typeof b.durationTime&&(b.durationTime=t(b.durationTime)),"now"==b.scrollDefault)b.scrollDefault=function(){return b.roundingFunction(t(new Date),b)};else if(b.scrollDefault&&"function"!=typeof b.scrollDefault){var c=b.scrollDefault;b.scrollDefault=function(){return b.roundingFunction(t(c),b)}}else b.minTime&&(b.scrollDefault=function(){return b.roundingFunction(b.minTime,b)});if("string"===a.type(b.timeFormat)&&b.timeFormat.match(/[gh]/)&&(b._twelveHourTime=!0),b.showOnFocus===!1&&b.showOn.indexOf("focus")!=-1&&b.showOn.splice(b.showOn.indexOf("focus"),1),b.disableTimeRanges.length>0){for(var d in b.disableTimeRanges)b.disableTimeRanges[d]=[t(b.disableTimeRanges[d][0]),t(b.disableTimeRanges[d][1])];b.disableTimeRanges=b.disableTimeRanges.sort(function(a,b){return a[0]-b[0]});for(var d=b.disableTimeRanges.length-1;d>0;d--)b.disableTimeRanges[d][0]<=b.disableTimeRanges[d-1][1]&&(b.disableTimeRanges[d-1]=[Math.min(b.disableTimeRanges[d][0],b.disableTimeRanges[d-1][0]),Math.max(b.disableTimeRanges[d][1],b.disableTimeRanges[d-1][1])],b.disableTimeRanges.splice(d,1))}return b}function d(b){var c=b.data("timepicker-settings"),d=b.data("timepicker-list");if(d&&d.length&&(d.remove(),b.data("timepicker-list",!1)),c.useSelect){d=a("<select />",{"class":"ui-timepicker-select"}),b.attr("name")&&d.attr("name","ui-timepicker-"+b.attr("name"));var g=d}else{d=a("<ul />",{"class":"ui-timepicker-list"});var g=a("<div />",{"class":"ui-timepicker-wrapper",tabindex:-1});g.css({display:"none",position:"absolute"}).append(d)}if(c.noneOption)if(c.noneOption===!0&&(c.noneOption=c.useSelect?"Time...":"None"),a.isArray(c.noneOption)){for(var i in c.noneOption)if(parseInt(i,10)==i){var k=e(c.noneOption[i],c.useSelect);d.append(k)}}else{var k=e(c.noneOption,c.useSelect);d.append(k)}if(c.className&&g.addClass(c.className),(null!==c.minTime||null!==c.durationTime)&&c.showDuration){"function"==typeof c.step?"function":c.step;g.addClass("ui-timepicker-with-duration"),g.addClass("ui-timepicker-step-"+c.step)}var l=c.minTime;"function"==typeof c.durationTime?l=t(c.durationTime()):null!==c.durationTime&&(l=c.durationTime);var n=null!==c.minTime?c.minTime:0,o=null!==c.maxTime?c.maxTime:n+v-1;o<n&&(o+=v),o===v-1&&"string"===a.type(c.timeFormat)&&c.show2400&&(o=v);var p=c.disableTimeRanges,w=0,x=p.length,z=c.step;"function"!=typeof z&&(z=function(){return c.step});for(var i=n,A=0;i<=o;A++,i+=60*z(A)){var B=i,C=s(B,c);if(c.useSelect){var D=a("<option />",{value:C});D.text(C)}else{var D=a("<li />");D.addClass(B%v<v/2?"ui-timepicker-am":"ui-timepicker-pm"),D.data("time",u(B,c)),D.text(C)}if((null!==c.minTime||null!==c.durationTime)&&c.showDuration){var E=r(i-l,c.step);if(c.useSelect)D.text(D.text()+" ("+E+")");else{var F=a("<span />",{"class":"ui-timepicker-duration"});F.text(" ("+E+")"),D.append(F)}}w<x&&(B>=p[w][1]&&(w+=1),p[w]&&B>=p[w][0]&&B<p[w][1]&&(c.useSelect?D.prop("disabled",!0):D.addClass("ui-timepicker-disabled"))),d.append(D)}if(g.data("timepicker-input",b),b.data("timepicker-list",g),c.useSelect)b.val()&&d.val(f(t(b.val()),c)),d.on("focus",function(){a(this).data("timepicker-input").trigger("showTimepicker")}),d.on("blur",function(){a(this).data("timepicker-input").trigger("hideTimepicker")}),d.on("change",function(){m(b,a(this).val(),"select")}),m(b,d.val(),"initial"),b.hide().after(d);else{var G=c.appendTo;"string"==typeof G?G=a(G):"function"==typeof G&&(G=G(b)),G.append(g),j(b,d),d.on("mousedown click","li",function(c){b.off("focus.timepicker"),b.on("focus.timepicker-ie-hack",function(){b.off("focus.timepicker-ie-hack"),b.on("focus.timepicker",y.show)}),h(b)||b[0].focus(),d.find("li").removeClass("ui-timepicker-selected"),a(this).addClass("ui-timepicker-selected"),q(b)&&(b.trigger("hideTimepicker"),d.on("mouseup.timepicker click.timepicker","li",function(a){d.off("mouseup.timepicker click.timepicker"),g.hide()}))})}}function e(b,c){var d,e,f;return"object"==typeof b?(d=b.label,e=b.className,f=b.value):"string"==typeof b?(d=b,f=""):a.error("Invalid noneOption value"),c?a("<option />",{value:f,"class":e,text:d}):a("<li />",{"class":e,text:d}).data("time",String(f))}function f(a,b){if(a=b.roundingFunction(a,b),null!==a)return s(a,b)}function g(b){if(b.target!=window){var c=a(b.target);c.closest(".ui-timepicker-input").length||c.closest(".ui-timepicker-wrapper").length||(y.hide(),a(document).unbind(".ui-timepicker"),a(window).unbind(".ui-timepicker"))}}function h(a){var b=a.data("timepicker-settings");return(window.navigator.msMaxTouchPoints||"ontouchstart"in document)&&b.disableTouchKeyboard}function i(b,c,d){if(!d&&0!==d)return!1;var e=b.data("timepicker-settings"),f=!1,d=e.roundingFunction(d,e);return c.find("li").each(function(b,c){var e=a(c);if("number"==typeof e.data("time"))return e.data("time")==d?(f=e,!1):void 0}),f}function j(a,b){b.find("li").removeClass("ui-timepicker-selected");var c=a.data("timepicker-settings"),d=t(l(a),c);if(null!==d){var e=i(a,b,d);if(e){var f=e.offset().top-b.offset().top;(f+e.outerHeight()>b.outerHeight()||f<0)&&b.scrollTop(b.scrollTop()+e.position().top-e.outerHeight()),(c.forceRoundTime||e.data("time")===d)&&e.addClass("ui-timepicker-selected")}}}function k(b,c){if("timepicker"!=c){var d=a(this);if(""===this.value)return void m(d,null,c);if(!d.is(":focus")||b&&"change"==b.type){var e=d.data("timepicker-settings"),f=t(this.value,e);if(null===f)return void d.trigger("timeFormatError");var g=!1;if(null!==e.minTime&&null!==e.maxTime&&(f<e.minTime||f>e.maxTime)&&(g=!0),a.each(e.disableTimeRanges,function(){if(f>=this[0]&&f<this[1])return g=!0,!1}),e.forceRoundTime){var h=e.roundingFunction(f,e);h!=f&&(f=h,c=null)}var i=s(f,e);g?(m(d,i,"error")||b&&"change"==b.type)&&d.trigger("timeRangeError"):m(d,i,c)}}}function l(a){return a.is("input")?a.val():a.data("ui-timepicker-value")}function m(a,b,c){if(a.is("input")){a.val(b);var d=a.data("timepicker-settings");d.useSelect&&"select"!=c&&a.data("timepicker-list")&&a.data("timepicker-list").val(f(t(b),d))}return a.data("ui-timepicker-value")!=b?(a.data("ui-timepicker-value",b),"select"==c?a.trigger("selectTime").trigger("changeTime").trigger("change","timepicker"):["error","initial"].indexOf(c)==-1&&a.trigger("changeTime"),!0):(["error","initial"].indexOf(c)==-1&&a.trigger("selectTime"),!1)}function n(a){switch(a.keyCode){case 13:case 9:return;default:a.preventDefault()}}function o(c){var d=a(this),e=d.data("timepicker-list");if(!e||!b(e)){if(40!=c.keyCode)return!0;
7y.show.call(d.get(0)),e=d.data("timepicker-list"),h(d)||d.focus()}switch(c.keyCode){case 13:return q(d)&&(k.call(d.get(0),{type:"change"}),y.hide.apply(this)),c.preventDefault(),!1;case 38:var f=e.find(".ui-timepicker-selected");return f.length?f.is(":first-child")||(f.removeClass("ui-timepicker-selected"),f.prev().addClass("ui-timepicker-selected"),f.prev().position().top<f.outerHeight()&&e.scrollTop(e.scrollTop()-f.outerHeight())):(e.find("li").each(function(b,c){if(a(c).position().top>0)return f=a(c),!1}),f.addClass("ui-timepicker-selected")),!1;case 40:return f=e.find(".ui-timepicker-selected"),0===f.length?(e.find("li").each(function(b,c){if(a(c).position().top>0)return f=a(c),!1}),f.addClass("ui-timepicker-selected")):f.is(":last-child")||(f.removeClass("ui-timepicker-selected"),f.next().addClass("ui-timepicker-selected"),f.next().position().top+2*f.outerHeight()>e.outerHeight()&&e.scrollTop(e.scrollTop()+f.outerHeight())),!1;case 27:e.find("li").removeClass("ui-timepicker-selected"),y.hide();break;case 9:y.hide();break;default:return!0}}function p(c){var d=a(this),e=d.data("timepicker-list"),f=d.data("timepicker-settings");if(!e||!b(e)||f.disableTextInput)return!0;if("paste"===c.type||"cut"===c.type)return void setTimeout(function(){f.typeaheadHighlight?j(d,e):e.hide()},0);switch(c.keyCode){case 96:case 97:case 98:case 99:case 100:case 101:case 102:case 103:case 104:case 105:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 65:case 77:case 80:case 186:case 8:case 46:f.typeaheadHighlight?j(d,e):e.hide()}}function q(a){var b=a.data("timepicker-settings"),c=a.data("timepicker-list"),d=null,e=c.find(".ui-timepicker-selected");return!e.hasClass("ui-timepicker-disabled")&&(e.length&&(d=e.data("time")),null!==d&&("string"!=typeof d&&(d=s(d,b)),m(a,d,"select")),!0)}function r(a,b){a=Math.abs(a);var c,d,e=Math.round(a/60),f=[];return e<60?f=[e,w.mins]:(c=Math.floor(e/60),d=e%60,30==b&&30==d&&(c+=w.decimal+5),f.push(c),f.push(1==c?w.hr:w.hrs),30!=b&&d&&(f.push(d),f.push(w.mins))),f.join(" ")}function s(b,c){if("number"!=typeof b)return null;var d=parseInt(b%60),e=parseInt(b/60%60),f=parseInt(b/3600%24),g=new Date(1970,0,2,f,e,d,0);if(isNaN(g.getTime()))return null;if("function"===a.type(c.timeFormat))return c.timeFormat(g);for(var h,i,j="",k=0;k<c.timeFormat.length;k++)switch(i=c.timeFormat.charAt(k)){case"a":j+=g.getHours()>11?w.pm:w.am;break;case"A":j+=g.getHours()>11?w.PM:w.AM;break;case"g":h=g.getHours()%12,j+=0===h?"12":h;break;case"G":h=g.getHours(),b===v&&(h=c.show2400?24:0),j+=h;break;case"h":h=g.getHours()%12,0!==h&&h<10&&(h="0"+h),j+=0===h?"12":h;break;case"H":h=g.getHours(),b===v&&(h=c.show2400?24:0),j+=h>9?h:"0"+h;break;case"i":var e=g.getMinutes();j+=e>9?e:"0"+e;break;case"s":d=g.getSeconds(),j+=d>9?d:"0"+d;break;case"\\":k++,j+=c.timeFormat.charAt(k);break;default:j+=i}return j}function t(a,b){if(""===a||null===a)return null;if("object"==typeof a)return 3600*a.getHours()+60*a.getMinutes()+a.getSeconds();if("string"!=typeof a)return a;a=a.toLowerCase().replace(/[\s\.]/g,""),"a"!=a.slice(-1)&&"p"!=a.slice(-1)||(a+="m");var c="("+w.am.replace(".","")+"|"+w.pm.replace(".","")+"|"+w.AM.replace(".","")+"|"+w.PM.replace(".","")+")?",d=new RegExp("^"+c+"([0-9]?[0-9])\\W?([0-5][0-9])?\\W?([0-5][0-9])?"+c+"$"),e=a.match(d);if(!e)return null;var f=parseInt(1*e[2],10),g=e[1]||e[5],h=f,i=1*e[3]||0,j=1*e[4]||0;if(f<=12&&g){var k=g==w.pm||g==w.PM;h=12==f?k?12:0:f+(k?12:0)}else if(b){var l=3600*f+60*i+j;if(l>=v+(b.show2400?1:0)){if(b.wrapHours===!1)return null;h=f%24}}var m=3600*h+60*i+j;if(f<12&&!g&&b&&b._twelveHourTime&&b.scrollDefault){var n=m-b.scrollDefault();n<0&&n>=v/-2&&(m=(m+v/2)%v)}return m}function u(a,b){return a==v&&b.show2400?a:a%v}var v=86400,w={am:"am",pm:"pm",AM:"AM",PM:"PM",decimal:".",mins:"mins",hr:"hr",hrs:"hrs"},x={appendTo:"body",className:null,closeOnWindowScroll:!1,disableTextInput:!1,disableTimeRanges:[],disableTouchKeyboard:!1,durationTime:null,forceRoundTime:!1,maxTime:null,minTime:null,noneOption:!1,orientation:"l",roundingFunction:function(a,b){if(null===a)return null;if("number"!=typeof b.step)return a;var c=a%(60*b.step),d=b.minTime||0;return c-=d%(60*b.step),c>=30*b.step?a+=60*b.step-c:a-=c,u(a,b)},scrollDefault:null,selectOnBlur:!1,show2400:!1,showDuration:!1,showOn:["click","focus"],showOnFocus:!0,step:30,stopScrollPropagation:!1,timeFormat:"g:ia",typeaheadHighlight:!0,useSelect:!1,wrapHours:!0},y={init:function(b){return this.each(function(){var e=a(this),f=[];for(var g in x)e.data(g)&&(f[g]=e.data(g));var h=a.extend({},x,b,f);
7if(h.lang&&(w=a.extend(w,h.lang)),h=c(h),e.data("timepicker-settings",h),e.addClass("ui-timepicker-input"),h.useSelect)d(e);else{if(e.prop("autocomplete","off"),h.showOn)for(var i in h.showOn)e.on(h.showOn[i]+".timepicker",y.show);e.on("change.timepicker",k),e.on("keydown.timepicker",o),e.on("keyup.timepicker",p),h.disableTextInput&&e.on("keydown.timepicker",n),e.on("cut.timepicker",p),e.on("paste.timepicker",p),k.call(e.get(0),null,"initial")}})},show:function(c){var e=a(this),f=e.data("timepicker-settings");if(c&&c.preventDefault(),f.useSelect)return void e.data("timepicker-list").focus();h(e)&&e.blur();var k=e.data("timepicker-list");if(!e.prop("readonly")&&(k&&0!==k.length&&"function"!=typeof f.durationTime||(d(e),k=e.data("timepicker-list")),!b(k))){e.data("ui-timepicker-value",e.val()),j(e,k),y.hide(),k.show();var m={};f.orientation.match(/r/)?m.left=e.offset().left+e.outerWidth()-k.outerWidth()+parseInt(k.css("marginLeft").replace("px",""),10):m.left=e.offset().left+parseInt(k.css("marginLeft").replace("px",""),10);var n;n=f.orientation.match(/t/)?"t":f.orientation.match(/b/)?"b":e.offset().top+e.outerHeight(!0)+k.outerHeight()>a(window).height()+a(window).scrollTop()?"t":"b","t"==n?(k.addClass("ui-timepicker-positioned-top"),m.top=e.offset().top-k.outerHeight()+parseInt(k.css("marginTop").replace("px",""),10)):(k.removeClass("ui-timepicker-positioned-top"),m.top=e.offset().top+e.outerHeight()+parseInt(k.css("marginTop").replace("px",""),10)),k.offset(m);var o=k.find(".ui-timepicker-selected");if(!o.length){var p=t(l(e));null!==p?o=i(e,k,p):f.scrollDefault&&(o=i(e,k,f.scrollDefault()))}if(o.length&&!o.hasClass("ui-timepicker-disabled")||(o=k.find("li:not(.ui-timepicker-disabled):first")),o&&o.length){var q=k.scrollTop()+o.position().top-o.outerHeight();k.scrollTop(q)}else k.scrollTop(0);return f.stopScrollPropagation&&a(document).on("wheel.ui-timepicker",".ui-timepicker-wrapper",function(b){b.preventDefault();var c=a(this).scrollTop();a(this).scrollTop(c+b.originalEvent.deltaY)}),a(document).on("touchstart.ui-timepicker mousedown.ui-timepicker",g),a(window).on("resize.ui-timepicker",g),f.closeOnWindowScroll&&a(document).on("scroll.ui-timepicker",g),e.trigger("showTimepicker"),this}},hide:function(c){var d=a(this),e=d.data("timepicker-settings");return e&&e.useSelect&&d.blur(),a(".ui-timepicker-wrapper").each(function(){var c=a(this);if(b(c)){var d=c.data("timepicker-input"),e=d.data("timepicker-settings");e&&e.selectOnBlur&&q(d),c.hide(),d.trigger("hideTimepicker")}}),this},option:function(b,e){return"string"==typeof b&&"undefined"==typeof e?a(this).data("timepicker-settings")[b]:this.each(function(){var f=a(this),g=f.data("timepicker-settings"),h=f.data("timepicker-list");"object"==typeof b?g=a.extend(g,b):"string"==typeof b&&(g[b]=e),g=c(g),f.data("timepicker-settings",g),k.call(f.get(0),{type:"change"},"initial"),h&&(h.remove(),f.data("timepicker-list",!1)),g.useSelect&&d(f)})},getSecondsFromMidnight:function(){return t(l(this))},getTime:function(a){var b=this,c=l(b);if(!c)return null;var d=t(c);if(null===d)return null;a||(a=new Date);var e=new Date(a);return e.setHours(d/3600),e.setMinutes(d%3600/60),e.setSeconds(d%60),e.setMilliseconds(0),e},isVisible:function(){var a=this,c=a.data("timepicker-list");return!(!c||!b(c))},setTime:function(a){var b=this,c=b.data("timepicker-settings");if(c.forceRoundTime)var d=f(t(a),c);else var d=s(t(a),c);return a&&null===d&&c.noneOption&&(d=a),m(b,d,"initial"),k.call(b.get(0),{type:"change"},"initial"),b.data("timepicker-list")&&j(b,b.data("timepicker-list")),this},remove:function(){var a=this;if(a.hasClass("ui-timepicker-input")){var b=a.data("timepicker-settings");return a.removeAttr("autocomplete","off"),a.removeClass("ui-timepicker-input"),a.removeData("timepicker-settings"),a.off(".timepicker"),a.data("timepicker-list")&&a.data("timepicker-list").remove(),b.useSelect&&a.show(),a.removeData("timepicker-list"),this}}};a.fn.timepicker=function(b){return this.length?y[b]?this.hasClass("ui-timepicker-input")?y[b].apply(this,Array.prototype.slice.call(arguments,1)):this:"object"!=typeof b&&b?void a.error("Method "+b+" does not exist on jQuery.timepicker"):y.init.apply(this,arguments):this}}); 8; 9/********************************************** 10 * @File Name: jquery.mb.YTPlayer.src.js 11 * @Author: Matteo Bicocchi 12 * @Date: 2020-03-16 13 * @Email: [email protected] 14 * 15 * @Last Modified by: Matteo Bicocchi 16 * @Last Modified time: 2020-03-18 17 * @Copyright: 2020. Matteo Bicocchi 18 * 19 * Open Lab s.r.l., Florence - Italy 20 * @blog: http://pupunzi.open-lab.com
vendor: 74,946 bytes, lines 21-2785
21 * @site: http://pupunzi.com 22 ****************************************************/ 23 24 25var ytp = ytp || {}; 26 27let YTPRndSuffix = new Date().getTime(); 28let YTPTimerLabels = { 29 init : "YTPlayerInit_" + YTPRndSuffix, 30 startPlaying: "YTPlayerStartPlay_" + YTPRndSuffix 31}; 32 33function onYouTubeIframeAPIReady() { 34 if (ytp.YTAPIReady) 35 return; 36 37 ytp.YTAPIReady = true; 38 jQuery(document).trigger('YTAPIReady') 39} 40 41let getYTPVideoID = function (url) { 42 let videoID, playlistID; 43 if (url.indexOf('youtu.be') > 0 || url.indexOf('youtube.com/embed') > 0) { 44 videoID = url.substr(url.lastIndexOf('/') + 1, url.length); 45 playlistID = videoID.indexOf('?list=') > 0 ? videoID.substr(videoID.lastIndexOf('='), videoID.length) : null; 46 videoID = playlistID ? videoID.substr(0, videoID.lastIndexOf('?')) : videoID 47 } else if (url.indexOf('http') > -1) { 48 //videoID = url.match( /([\/&]v\/([^&#]*))|([\\?&]v=([^&#]*))/ )[ 1 ]; 49 videoID = url.match(/[\\?&]v=([^&#]*)/)[1]; 50 playlistID = url.indexOf('list=') > 0 ? url.match(/[\\?&]list=([^&#]*)/)[1] : null 51 } else { 52 videoID = url.length > 15 ? null : url; 53 playlistID = videoID ? null : url 54 } 55 return { 56 videoID : videoID, 57 playlistID: playlistID 58 } 59}; 60 61(function (jQuery, ytp) { 62 63 jQuery.mbYTPlayer = { 64 name : 'jquery.mb.YTPlayer', 65 version: '3.3.9', 66 build : '7581', 67 author : 'Matteo Bicocchi (pupunzi)', 68 apiKey : '', 69 70 /* 71 * Default options for the player 72 */ 73 defaults : { 74 /** 75 videoURL (string) 76 the complete Youtube video URL or the short url or the videoID 77 */ 78 videoURL: null, 79 80 /** 81 containment (string) 82 default containment for the player 83 */ 84 containment: 'body', 85 86 /** 87 ratio (string or number) 88 "auto", "16/9", "4/3" or number: 4/3, 16/9 89 */ 90 ratio: 'auto', 91 92 /** 93 fadeOnStartTime (int) 94 fade in timing at video start 95 */ 96 fadeOnStartTime: 1000, 97 98 /** 99 startAt (int) 100 start second 101 */ 102 startAt: 0, 103 104 /** 105 stopAt (int) 106 stop second 107 */ 108 stopAt: 0, 109 110 /** 111 autoPlay (bool) 112 on page load video should start or pause 113 */ 114 autoPlay: true, 115 116 /** 117 delayAtStart (bool) 118 If the YT API don't fire the event the player will try to start anyway after... 119 */ 120 delayAtStart: 1000, 121 122 /** 123 coverImage (string) 124 The path to the image to be used as cover if the autoPlay option is set to false 125 */ 126 coverImage: false, 127 128 /** 129 loop (bool or int) 130 video should loop or not; if number it will loop for the specified times 131 */ 132 loop: true, 133 134 /** 135 addRaster (bool) 136 shows a raster image over the video (added via CSS) 137 You can change the raster image via CSS: 138 .YTPOverlay.raster { background: url(images/raster.png)} 139 */ 140 addRaster: false, 141 142 /** 143 mask (bool or object) the key is the second and the value is the path to the image 144 Ex: mask:{ 0:'assets/mask-1.png', 5:'assets/mask-2.png', 30: false, 50:'assets/mask-3.png'} 145 */ 146 mask: false, 147 148 /** 149 opacity (int) 150 0 to 1 151 */ 152 opacity: 1, 153 154 /** 155 quality (string) 156 @deprecated 157 158 setPlaybackQuality has been deprecated on the YT API and doesn't work anymore 159 âsmallâ, âmediumâ, âlargeâ, âhd720â, âhd1080â, âhighresâ, "default" 160 */ 161 quality: 'default', 162 163 /** 164 vol (int) 165 0 to 100 166 */ 167 vol: 50, 168 169 /** 170 mute (bool) 171 mute the video at start 172 */ 173 mute: false, 174 175 /** 176 showControls (bool) 177 shows the control bar at the bottom of the containment 178 */ 179 showControls: true, 180 181 /** 182 anchor (string) 183 center,top,bottom,left,right combined in pair 184 */ 185 anchor: 'center,center', 186 187 /** 188 showAnnotations (bool) 189 display the annotations on video 190 */ 191 showAnnotations: false, 192 193 /** 194 cc_load_policy (bool) 195 display the subtitles 196 */ 197 cc_load_policy: false, 198 199 /** 200 showYTLogo (bool) 201 display the Youtube logotype inside the button bar 202 */ 203 showYTLogo: true, 204 205 /** 206 useOnMobile (bool) 207 activate the player also on mobile 208 */ 209 useOnMobile: true, 210 211 /** 212 playOnlyIfVisible (bool) 213 play the video only if the containment is on screen 214 */ 215 playOnlyIfVisible: false, 216 217 /** 218 onScreenPercentage (bool) 219 percentage of the player height the video should stop or start when visible 220 */ 221 onScreenPercentage: 30, 222 223 /** 224 * goFullScreenOnPlay (bool) 225 * if the player containment is set to "self" this allow the video to go fullscreen when played 226 */ 227 goFullScreenOnPlay: false, 228 229 /** 230 stopMovieOnBlur (bool) 231 stop the video if the window loose the focus 232 */ 233 stopMovieOnBlur: true, 234 235 /** 236 realfullscreen (bool) 237 the video when in full screen covers all the display 238 */ 239 realFullscreen: true, 240 241 /** 242 optimizeDisplay (bool) 243 The video always fit the containment without displaying the black strips 244 */ 245 optimizeDisplay: true, 246 247 /** 248 abundance (bool) 249 the abudance of the video size 250 */ 251 abundance: 0.3, 252 253 /** 254 gaTrack (bool) 255 track the video plays on GA 256 */ 257 gaTrack: true, 258 259 /** 260 remember_last_time (bool) 261 when the page is reloaded the video will start from the last position 262 */ 263 remember_last_time: false, 264 265 /** 266 addFilters (bool or string) 267 add one or more CSS filters as object to the video 268 Ex: {sepia: 50, hue_rotate : 220} 269 */ 270 addFilters: false, 271 272 /** 273 useNoCookie (bool) 274 use https://www.youtube-nocookie.com host to serve the video 275 */ 276 useNoCookie: true, 277 278 /** 279 onReady (function) 280 a callback function fired once the player is ready 281 */ 282 onReady: function (player) { 283 }, 284 285 /** 286 onReady (function) 287 a callback function fired if there's an error 288 */ 289 onError: function (player, err) { 290 }, 291 292 /** 293 onEnd (function) 294 a callback function fired when the video ends 295 */ 296 onEnd: function () { 297 } 298 }, 299 /** 300 * @fontface icons 301 * */ 302 controls : { 303 play : 'P', 304 pause : 'p', 305 mute : 'M', 306 unmute : 'A', 307 onlyYT : 'O', 308 showSite: 'R', 309 ytLogo : 'Y' 310 }, 311 controlBar : null, 312 locationProtocol: 'https:', 313 314 /** 315 * Applicable filters 316 */ 317 defaultFilters: { 318 grayscale : {value: 0, unit: '%'}, 319 hue_rotate: {value: 0, unit: 'deg'}, 320 invert : {value: 0, unit: '%'}, 321 opacity : {value: 0, unit: '%'}, 322 saturate : {value: 0, unit: '%'}, 323 sepia : {value: 0, unit: '%'}, 324 brightness: {value: 0, unit: '%'}, 325 contrast : {value: 0, unit: '%'}, 326 blur : {value: 0, unit: 'px'} 327 }, 328 329 /** 330 * build the player 331 * @param options 332 * @returns [players] 333 */ 334 buildPlayer: function (options) { 335 336 if (!ytp.YTAPIReady && typeof window.YT === 'undefined') { 337 jQuery('#YTAPI').remove(); 338 let tag = jQuery('<script>').attr({ 339 'src': 'https://www.youtube.com/iframe_api?v=' + jQuery.mbYTPlayer.version, 340 'id' : 'YTAPI' 341 }); 342 jQuery('head').prepend(tag) 343 } else { 344 setTimeout(function () { 345 jQuery(document).trigger('YTAPIReady'); 346 ytp.YTAPIReady = true 347 }, 100) 348 } 349 350 function isIframe() { 351 let isIfr = false; 352 try { 353 if (self.location.href !== top.location.href) isIfr = true 354 } catch (e) { 355 isIfr = true 356 } 357 return isIfr 358 } 359 360 return this.each(function () { 361 let YTPlayer = this; 362 let $YTPlayer = jQuery(YTPlayer); 363 $YTPlayer.hide(); 364 YTPlayer.loop = 0; 365 YTPlayer.state = 0; 366 YTPlayer.filters = jQuery.extend(true, {}, jQuery.mbYTPlayer.defaultFilters); 367 YTPlayer.filtersEnabled = true; 368 YTPlayer.id = YTPlayer.id || 'YTP_' + new Date().getTime(); 369 $YTPlayer.addClass('mb_YTPlayer'); 370 371 /** 372 Set properties 373 */ 374 let property = $YTPlayer.data('property') && typeof $YTPlayer.data('property') == 'string' ? 375 eval('(' + $YTPlayer.data('property') + ')') : 376 $YTPlayer.data('property'); 377 378 if (typeof property !== 'object') 379 property = {}; 380 381 YTPlayer.opt = jQuery.extend(true, {}, jQuery.mbYTPlayer.defaults, YTPlayer.opt, options, property); 382 383 YTPRndSuffix = getYTPVideoID(YTPlayer.opt.videoURL).videoID; 384 YTPTimerLabels = { 385 init : "YTPlayerInit_" + YTPRndSuffix, 386 startPlaying: "YTPlayerStartPlay_" + YTPRndSuffix 387 }; 388 389 console.time(YTPTimerLabels.init); 390 console.time(YTPTimerLabels.startPlaying); 391 392 YTPlayer.opt.elementId = YTPlayer.id; 393 394 if (YTPlayer.opt.vol === 0) { 395 YTPlayer.opt.vol = 1; 396 YTPlayer.opt.mute = true 397 } 398 399 if (YTPlayer.opt.loop && typeof YTPlayer.opt.loop === 'boolean') { 400 YTPlayer.opt.loop = 9999 401 } 402 403 /** 404 Disable fullScreen if is in an iframe or full-screen API is not available 405 */ 406 let fullScreenAvailable = document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled; 407 YTPlayer.opt.realFullscreen = isIframe() || !fullScreenAvailable ? false : YTPlayer.opt.realFullscreen; 408 409 /** 410 Manage annotations 411 */ 412 YTPlayer.opt.showAnnotations = YTPlayer.opt.showAnnotations ? '1' : '3'; 413 414 /** 415 Manage show subtitle and caption 416 */ 417 YTPlayer.opt.cc_load_policy = YTPlayer.opt.cc_load_policy ? '1' : '0'; 418 419 /** 420 Manage cover image 421 */ 422 YTPlayer.opt.coverImage = YTPlayer.opt.coverImage || YTPlayer.opt.backgroundImage; 423 424 /** 425 Manage Quality 426 the setPlaybackQuality has been deprecated by YT 427 */ 428 YTPlayer.opt.quality = 'hd1080'; 429 430 YTPlayer.opt.containment = YTPlayer.opt.containment === 'self' ? $YTPlayer : jQuery(YTPlayer.opt.containment); 431 YTPlayer.isRetina = (window.retina || window.devicePixelRatio > 1); 432 433 YTPlayer.opt.ratio = YTPlayer.opt.ratio === 'auto' ? 16 / 9 : YTPlayer.opt.ratio; 434 YTPlayer.opt.ratio = eval(YTPlayer.opt.ratio); 435 436 let origContainmentBackground = YTPlayer.opt.containment.css('background-image'); 437 origContainmentBackground = (origContainmentBackground === 'none') ? null : origContainmentBackground; 438 YTPlayer.orig_containment_background = origContainmentBackground; 439 440 if (!$YTPlayer.attr('id')) 441 $YTPlayer.attr('id', 'ytp_' + new Date().getTime()); 442 443 YTPlayer.playerID = 'iframe_' + YTPlayer.id; 444 445 YTPlayer.isAlone = false; 446 YTPlayer.hasFocus = true; 447 YTPlayer.videoID = YTPlayer.opt.videoURL ? 448 getYTPVideoID(YTPlayer.opt.videoURL).videoID : $YTPlayer.attr('href') ? 449 getYTPVideoID($YTPlayer.attr('href')).videoID : 450 false; 451 452 /** 453 Check if it is a video list 454 */ 455 YTPlayer.playlistID = YTPlayer.opt.videoURL ? 456 getYTPVideoID(YTPlayer.opt.videoURL).playlistID : $YTPlayer.attr('href') ? 457 getYTPVideoID($YTPlayer.attr('href')).playlistID : 458 false; 459 460 let start_from_last = 0; 461 if (jQuery.mbCookie.get('YTPlayer_start_from' + YTPlayer.videoID)) 462 start_from_last = parseFloat(jQuery.mbCookie.get('YTPlayer_start_from' + YTPlayer.videoID)); 463 if (YTPlayer.opt.remember_last_time && start_from_last) { 464 YTPlayer.start_from_last = start_from_last; 465 jQuery.mbCookie.remove('YTPlayer_start_from' + YTPlayer.videoID) 466 } 467 468 YTPlayer.isPlayer = $YTPlayer.is(YTPlayer.opt.containment); 469 YTPlayer.isBackground = YTPlayer.opt.containment.is('body'); 470 471 if (YTPlayer.isBackground && ytp.backgroundIsInited) 472 return; 473 474 /** 475 Hide the placeholder if it's not the target of the player 476 */ 477 if (YTPlayer.isPlayer) 478 $YTPlayer.show(); 479 480 /** 481 create the overlay 482 */ 483 YTPlayer.overlay = jQuery('<div/>').css({ 484 position: 'absolute', 485 top : 0, 486 left : 0, 487 width : '100%', 488 height : '100%' 489 }).addClass('YTPOverlay'); 490 491 $YTPlayer.changeCoverImage(); 492 493 /** 494 create the wrapper 495 */ 496 YTPlayer.wrapper = jQuery('<div/>').attr('id', 'wrapper_' + YTPlayer.id).css({ 497 position : 'absolute', 498 zIndex : 0, 499 minWidth : '100%', 500 minHeight: '100%', 501 left : 0, 502 top : 0, 503 overflow : 'hidden', 504 opacity : 0 505 }).addClass('mbYTP_wrapper'); 506 507 /** 508 If is an inline player toggle play if the overlay is clicked 509 */ 510 if (YTPlayer.isPlayer) { 511 let inlinePlayButtonCss = jQuery.mbBrowser.mobile ? "inlinePlayButtonMobile" : "inlinePlayButton"; 512 YTPlayer.inlinePlayButton = jQuery('<div/>').addClass(inlinePlayButtonCss).html(jQuery.mbYTPlayer.controls.play); 513 $YTPlayer.append(YTPlayer.inlinePlayButton); 514 YTPlayer.inlinePlayButton.on('click', function (e) { 515 516 $YTPlayer.YTPPlay(); 517 /** 518 * Hide the PLAY button on play 519 */ 520 YTPlayer.inlinePlayButton.hide(); 521 522 /** 523 * set the fullscreen on play 524 */ 525 if (YTPlayer.opt.goFullScreenOnPlay) { 526 $YTPlayer.YTPFullscreen(); 527 } 528 529 e.stopPropagation() 530 }); 531 532 if (YTPlayer.opt.autoPlay) 533 YTPlayer.inlinePlayButton.hide(); 534 535 YTPlayer.overlay.on('click', function () { 536 $YTPlayer.YTPTogglePlay(); 537 538 if (YTPlayer.opt.goFullScreenOnPlay) { 539 $YTPlayer.YTPFullscreen(); 540 } 541 542 }).css({cursor: 'pointer'}) 543 544 } 545 546 /** 547 create the playerBox where the YT iframe will be placed 548 */ 549 let playerBox = jQuery('<div/>').attr('id', YTPlayer.playerID).addClass('playerBox'); 550 playerBox.css({ 551 position: 'absolute', 552 zIndex : 0, 553 width : '100%', 554 height : '100%', 555 top : 0, 556 left : 0, 557 overflow: 'hidden', 558 opacity : 1 559 }); 560 561 YTPlayer.wrapper.append(playerBox); 562 playerBox.after(YTPlayer.overlay); 563 564 if (YTPlayer.isPlayer) { 565 YTPlayer.inlineWrapper = jQuery('<div/>').addClass('inline-YTPlayer'); 566 567 YTPlayer.inlineWrapper.css({ 568 position: 'relative', 569 maxWidth: YTPlayer.opt.containment.css('width') 570 }); 571 572 YTPlayer.opt.containment.css({ 573 position : 'relative', 574 paddingBottom: '56.25%', 575 overflow : 'hidden', 576 height : 0 577 }); 578 YTPlayer.opt.containment.wrap(YTPlayer.inlineWrapper) 579 } 580 581 /** 582 Loop all the elements inside the container and check if their position is not "static" 583 */ 584 YTPlayer.opt.containment.children().not('script, style').each(function () { 585 if (jQuery(this).css('position') === 'static') 586 jQuery(this).css('position', 'relative') 587 }); 588 589 if (YTPlayer.isBackground) { 590 jQuery('body').css({ 591 boxSizing: 'border-box' 592 }); 593 594 YTPlayer.wrapper.css({ 595 position: 'fixed', 596 top : 0, 597 left : 0, 598 zIndex : 0 599 }) 600 601 } else if (YTPlayer.opt.containment.css('position') === 'static') { 602 603 YTPlayer.opt.containment.css({ 604 position: 'relative' 605 }); 606 $YTPlayer.show() 607 } 608 YTPlayer.opt.containment.prepend(YTPlayer.wrapper); 609 610 if (!YTPlayer.isBackground) { 611 YTPlayer.overlay.on('mouseenter', function () { 612 if (YTPlayer.controlBar && YTPlayer.controlBar.length) 613 YTPlayer.controlBar.addClass('visible') 614 }).on('mouseleave', function () { 615 if (YTPlayer.controlBar && YTPlayer.controlBar.length) 616 YTPlayer.controlBar.removeClass('visible') 617 }) 618 } 619 620 if (jQuery.mbBrowser.mobile && !YTPlayer.opt.useOnMobile) { 621 if (YTPlayer.opt.coverImage) { 622 YTPlayer.wrapper.css({ 623 backgroundImage : 'url(' + YTPlayer.opt.coverImage + ')', 624 backgroundPosition: 'center center', 625 backgroundSize : 'cover', 626 backgroundRepeat : 'no-repeat', 627 opacity : 1 628 }); 629 630 YTPlayer.wrapper.css({opacity: 1}) 631 } 632 return $YTPlayer 633 } 634 635 /** 636 If is on device start playing on first touch 637 */ 638 if (jQuery.mbBrowser.mobile && YTPlayer.opt.autoPlay && YTPlayer.opt.useOnMobile) 639 jQuery('body').one('touchstart', function () { 640 YTPlayer.player.playVideo() 641 }); 642 643 jQuery(document).one('YTAPIReady', function () { 644 $YTPlayer.trigger('YTAPIReady_' + YTPlayer.id); 645 ytp.YTAPIReady = true 646 }); 647 648 YTPlayer.isOnScreen = jQuery.mbYTPlayer.isOnScreen(YTPlayer, YTPlayer.opt.onScreenPercentage); 649 650 $YTPlayer.one('YTAPIReady_' + YTPlayer.id, function () { 651 652 let YTPlayer = this; 653 let $YTPlayer = jQuery(YTPlayer); 654 655 if ((YTPlayer.isBackground && ytp.backgroundIsInited) || YTPlayer.isInit) 656 return; 657 658 if (YTPlayer.isBackground) 659 ytp.backgroundIsInited = true; 660 661 YTPlayer.opt.autoPlay = typeof YTPlayer.opt.autoPlay == 'undefined' ? (!!YTPlayer.isBackground) : YTPlayer.opt.autoPlay; 662 YTPlayer.opt.vol = YTPlayer.opt.vol ? YTPlayer.opt.vol : 100; 663 664 jQuery.mbYTPlayer.getDataFromAPI(YTPlayer); 665 666 jQuery(YTPlayer).on('YTPChanged', function (e) { 667 668 if (YTPlayer.isInit) 669 return; 670 671 YTPlayer.isInit = true; 672 673 /** Initialize the YT player ------------------------------------ 674 * Youtube player variables 675 * @type {{modestbranding: number, autoplay: number, controls: number, showinfo: number, rel: number, enablejsapi: number, version: number, playerapiid: string, origin: string, allowfullscreen: boolean, iv_load_policy: (string|*|jQuery.mbYTPlayer.opt.showAnnotations), playsinline: number}} 676 */ 677 let playerVars = { 678 'modestbranding' : 1, 679 'autoplay' : 0, 680 'controls' : 0, 681 'showinfo' : 0, 682 'rel' : 0, 683 'enablejsapi' : 1, 684 'version' : 3, 685 'playerapiid' : YTPlayer.playerID, 686 'origin' : '*', 687 'allowfullscreen': true, 688 'wmode' : 'transparent', 689 'iv_load_policy' : YTPlayer.opt.showAnnotations, 690 'cc_load_policy' : YTPlayer.opt.cc_load_policy, 691 'playsinline' : jQuery.mbBrowser.mobile && !YTPlayer.isPlayer ? 1 : 0, 692 693 /** 694 Check if the mbBrowser can play HTML5 videos 695 */ 696 'html5': document.createElement('video').canPlayType ? 1 : 0 697 }; 698 699 new YT.Player(YTPlayer.playerID, { 700 //videoId: YTPlayer.videoID.toString(), 701 host : YTPlayer.opt.useNoCookie ? 'https://www.youtube-nocookie.com' : 'https://www.youtube.com', 702 playerVars: playerVars, 703 events : { 704 'onReady' : function (event) { 705 YTPlayer.player = event.target; 706 YTPlayer.player.loadVideoById({ 707 videoId : YTPlayer.videoID.toString(), 708 suggestedQuality: YTPlayer.opt.quality 709 }); 710 711 $YTPlayer.trigger('YTPlayerIsReady_' + YTPlayer.id) 712 }, 713 /** 714 * on State Change 715 * @param event 716 * 717 * -1 (unstarted) 718 * 0 (ended) 719 * 1 (playing) 720 * 2 (paused) 721 * 3 (buffering) 722 * 5 (video cued) 723 */ 724 'onStateChange': function (event) { 725 726 if (typeof event.target.getPlayerState != 'function') 727 return; 728 729 let state = event.target.getPlayerState(); 730 731 if (YTPlayer.preventTrigger || YTPlayer.isStarting) { 732 YTPlayer.preventTrigger = false; 733 return 734 } 735 736 YTPlayer.state = state; 737 // console.debug(YTPlayer.state); 738 739 if (event.data === YT.PlayerState.PLAYING) { 740 event.target.setPlaybackQuality(YTPlayer.opt.quality) 741 } 742 743 let eventType; 744 switch (state) { 745 746 /** unstarted */ 747 case -1: 748 eventType = 'YTPUnstarted'; 749 break; 750 751 /** unstarted */ 752 case 0: 753 eventType = 'YTPRealEnd'; 754 break; 755 756 /** play */ 757 case 1: 758 eventType = 'YTPPlay'; 759 if (YTPlayer.controlBar.length) 760 YTPlayer.controlBar.find('.mb_YTPPlayPause').html(jQuery.mbYTPlayer.controls.pause); 761 762 if (YTPlayer.isPlayer) 763 YTPlayer.inlinePlayButton.hide(); 764 765 jQuery(document).off('mousedown.YTPstart'); 766 break; 767 768 /** pause */ 769 case 2: 770 eventType = 'YTPPause'; 771 if (YTPlayer.controlBar.length) 772 YTPlayer.controlBar.find('.mb_YTPPlayPause').html(jQuery.mbYTPlayer.controls.play); 773 774 if (YTPlayer.isPlayer) 775 YTPlayer.inlinePlayButton.show(); 776 break; 777 778 /** buffer */ 779 case 3: 780 // YTPlayer.player.setPlaybackQuality('default'); 781 YTPlayer.player.setPlaybackQuality(YTPlayer.opt.quality); 782 eventType = 'YTPBuffering'; 783 if (YTPlayer.controlBar.length) 784 YTPlayer.controlBar.find('.mb_YTPPlayPause').html(jQuery.mbYTPlayer.controls.play); 785 break; 786 787 /** cued */ 788 case 5: 789 eventType = 'YTPCued'; 790 break; 791 792 default: 793 break 794 } 795 796 /** 797 Trigger state events 798 */ 799 let YTPEvent = jQuery.Event(eventType); 800 YTPEvent.time = YTPlayer.currentTime; 801 jQuery(YTPlayer).trigger(YTPEvent) 802 }, 803 804 /** 805 * onPlaybackQualityChange 806 * @param e 807 */ 808 'onPlaybackQualityChange': function (e) { 809 let quality = e.target.getPlaybackQuality(); 810 let YTPQualityChange = jQuery.Event('YTPQualityChange'); 811 YTPQualityChange.quality = quality; 812 jQuery(YTPlayer).trigger(YTPQualityChange) 813 }, 814 815 /** 816 * onError 817 * @param err 818 * 819 2 â The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks. 820 5 â The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred. 821 100 â The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private. 822 101 â The owner of the requested video does not allow it to be played in embedded players. 823 150 â This error is the same as 101. It's just a 101 error in disguise! 824 */ 825 'onError': function (err) { 826 827 if (typeof YTPlayer.opt.onError == 'function') 828 YTPlayer.opt.onError($YTPlayer, err); 829 830 console.debug("error:", err); 831 832 switch (err.data) { 833 case 2: 834 console.error('video ID:: ' + YTPlayer.videoID + ': The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.'); 835 break; 836 case 5: 837 console.error('video ID:: ' + YTPlayer.videoID + ': The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.'); 838 break; 839 case 100: 840 console.error('video ID:: ' + YTPlayer.videoID + ': The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.'); 841 break; 842 case 101: 843 case 150: 844 console.error('video ID:: ' + YTPlayer.videoID + ': The video doesn\'t exist or The owner does not allow it to be played in embedded players.'); 845 break 846 } 847 848 if (YTPlayer.isList) 849 jQuery(YTPlayer).YTPPlayNext() 850 } 851 } 852 }); 853 854 $YTPlayer.on('YTPlayerIsReady_' + YTPlayer.id, function () { 855 856 if (YTPlayer.isReady) 857 return this; 858 859 YTPlayer.playerEl = YTPlayer.player.getIframe(); 860 jQuery(YTPlayer.playerEl).unselectable(); 861 $YTPlayer.optimizeDisplay(); 862 863 /** 864 * Optimize display on resize 865 */ 866 jQuery(window).off('resize.YTP_' + YTPlayer.id).on('resize.YTP_' + YTPlayer.id, function () { 867 $YTPlayer.optimizeDisplay() 868 }); 869 870 /** 871 * Optimize display on orientation change 872 */ 873 jQuery(window).off('orientationchange.YTP_' + YTPlayer.id).on('orientationchange.YTP_' + YTPlayer.id, function () { 874 $YTPlayer.optimizeDisplay() 875 }); 876 877 /** 878 * Set the time of the last visit progress 879 */ 880 if (YTPlayer.opt.remember_last_time) { 881 jQuery(window).on('unload.YTP_' + YTPlayer.id, function () { 882 let current_time = YTPlayer.player.getCurrentTime(); 883 jQuery.mbCookie.set('YTPlayer_start_from' + YTPlayer.videoID, current_time, 0) 884 }) 885 } 886 887 $YTPlayer.YTPCheckForState() 888 889 }) 890 }) 891 }); 892 893 $YTPlayer.off('YTPTime.mask'); 894 jQuery.mbYTPlayer.applyMask(YTPlayer); 895 896 console.timeEnd(YTPTimerLabels.init); 897 898 setTimeout(function () { 899 if (!ytp.YTAPIReady && typeof window.YT == "object") { 900 jQuery(document).trigger('YTAPIReady'); 901 ytp.YTAPIReady = true; 902 console.error("YTPlayer: More then a call to the YT API has been detected") 903 } 904 }, YTPlayer.opt.delayAtStart) 905 }) 906 }, 907 908 /** 909 * 910 * @param YTPlayer 911 * @param perc 912 * @returns {boolean} 913 */ 914 isOnScreen: function (YTPlayer, perc) { 915 perc = perc || 10; 916 let playerBox = YTPlayer.wrapper; 917 let winTop = jQuery(window).scrollTop(); 918 let winBottom = winTop + jQuery(window).height(); 919 920 let margin = (playerBox.height() * perc) / 100; 921 let elTop = playerBox.offset().top + margin; 922 let elBottom = playerBox.offset().top + (playerBox.height() - margin); 923 924 return ((elBottom <= winBottom) && (elTop >= winTop)) 925 }, 926 927 /** 928 * getDataFromAPI 929 * @param YTPlayer 930 */ 931 getDataFromAPI: function (YTPlayer) { 932 933 YTPlayer.videoData = jQuery.mbStorage.get('YTPlayer_data_' + YTPlayer.videoID); 934 if (YTPlayer.videoData) { 935 setTimeout(function () { 936 YTPlayer.dataReceived = true; 937 938 let YTPChanged = jQuery.Event('YTPChanged'); 939 YTPChanged.time = YTPlayer.currentTime; 940 YTPChanged.videoId = YTPlayer.videoID; 941 YTPChanged.opt = YTPlayer.opt; 942 943 //console.debug("videoData:",YTPlayer.videoData) 944 945 jQuery(YTPlayer).trigger(YTPChanged); 946 947 let YTPData = jQuery.Event('YTPData'); 948 YTPData.prop = {}; 949 950 for (let x in YTPlayer.videoData) 951 if (YTPlayer.videoData.hasOwnProperty(x)) 952 YTPData.prop[x] = YTPlayer.videoData[x]; 953 954 jQuery(YTPlayer).trigger(YTPData) 955 956 }, YTPlayer.opt.fadeOnStartTime); 957 958 YTPlayer.hasData = true 959 960 } else if (jQuery.mbYTPlayer.apiKey) { 961 962 /** 963 * Get video info from API3 (needs api key) 964 * snippet,player,contentDetails,statistics,status 965 */ 966 967 jQuery.getJSON('https://www.googleapis.com/youtube/v3/videos?id=' + YTPlayer.videoID + '&key=' + jQuery.mbYTPlayer.apiKey + '&part=snippet', function (data) { 968 YTPlayer.dataReceived = true; 969 970 let YTPChanged = jQuery.Event('YTPChanged'); 971 YTPChanged.time = YTPlayer.currentTime; 972 YTPChanged.videoId = YTPlayer.videoID; 973 jQuery(YTPlayer).trigger(YTPChanged); 974 975 function parseYTPlayer_data(data) { 976 YTPlayer.videoData = {}; 977 YTPlayer.videoData.id = YTPlayer.videoID; 978 YTPlayer.videoData.channelTitle = data.channelTitle; 979 YTPlayer.videoData.title = data.title; 980 YTPlayer.videoData.description = data.description.length < 400 ? data.description : data.description.substring(0, 400) + ' ...'; 981 YTPlayer.videoData.thumb_max = data.thumbnails.maxres ? data.thumbnails.maxres.url : null; 982 YTPlayer.videoData.thumb_high = data.thumbnails.high ? data.thumbnails.high.url : null; 983 YTPlayer.videoData.thumb_medium = data.thumbnails.medium ? data.thumbnails.medium.url : null; 984 jQuery.mbStorage.set('YTPlayer_data_' + YTPlayer.videoID, YTPlayer.videoData) 985 } 986 987 if (!data.items[0]) { 988 YTPlayer.videoData = {}; 989 YTPlayer.hasData = false 990 } else { 991 parseYTPlayer_data(data.items[0].snippet); 992 YTPlayer.hasData = true 993 } 994 995 let YTPData = jQuery.Event('YTPData'); 996 YTPData.prop = {}; 997 for (let x in YTPlayer.videoData) 998 YTPData.prop[x] = YTPlayer.videoData[x]; 999 1000 jQuery(YTPlayer).trigger(YTPData) 1001 }) 1002 .fail(function (jqxhr) { 1003 console.error("YT data error:: ", jqxhr); 1004 YTPlayer.hasData = false; 1005 1006 let YTPChanged = jQuery.Event('YTPChanged'); 1007 YTPChanged.time = YTPlayer.currentTime; 1008 YTPChanged.videoId = YTPlayer.videoID; 1009 jQuery(YTPlayer).trigger(YTPChanged) 1010 }) 1011 } else { 1012 1013 setTimeout(function () { 1014 let YTPChanged = jQuery.Event('YTPChanged'); 1015 YTPChanged.time = YTPlayer.currentTime; 1016 YTPChanged.videoId = YTPlayer.videoID; 1017 jQuery(YTPlayer).trigger(YTPChanged) 1018 }, 10); 1019 YTPlayer.videoData = null 1020 } 1021 1022 YTPlayer.opt.ratio = YTPlayer.opt.ratio == 'auto' ? 16 / 9 : YTPlayer.opt.ratio; 1023 1024 if (YTPlayer.isPlayer && !YTPlayer.opt.autoPlay) { //&& ( !jQuery.mbBrowser.mobile && !jQuery.isTablet ) 1025 YTPlayer.loading = jQuery('<div/>').addClass('loading').html('Loading').hide(); 1026 jQuery(YTPlayer).append(YTPlayer.loading); 1027 YTPlayer.loading.fadeIn() 1028 } 1029 }, 1030 1031 /** 1032 * removeStoredData 1033 */ 1034 removeStoredData: function () { 1035 jQuery.mbStorage.remove() 1036 }, 1037 1038 /** 1039 * getVideoData 1040 * @returns {*|YTPlayer.videoData} 1041 */ 1042 getVideoData: function () { 1043 let YTPlayer = this.get(0); 1044 return YTPlayer.videoData 1045 }, 1046 1047 /** 1048 * getVideoID 1049 * @returns {*|YTPlayer.videoID|boolean} 1050 */ 1051 getVideoID: function () { 1052 let YTPlayer = this.get(0); 1053 return YTPlayer.videoID || false 1054 }, 1055 1056 /** 1057 * getPlaylistID 1058 * @returns {*|YTPlayer.videoID|boolean} 1059 */ 1060 getPlaylistID : function () { 1061 let YTPlayer = this.get(0); 1062 return YTPlayer.playlistID || false 1063 }, 1064 /** 1065 * setVideoQuality 1066 * @deprecated 1067 * 1068 * @param quality 1069 * @returns {jQuery.mbYTPlayer} 1070 */ 1071 setVideoQuality: function (quality) { 1072 1073 let YTPlayer = this.get(0); 1074 let time = YTPlayer.player.getCurrentTime(); 1075 jQuery(YTPlayer).YTPPause(); 1076 YTPlayer.opt.quality = quality; 1077 YTPlayer.player.setPlaybackQuality(quality); 1078 YTPlayer.player.seekTo(time); // or set to CurrentTime using player.getCurrentTime() 1079 jQuery(YTPlayer).YTPPlay(); 1080 return this; 1081 }, 1082 1083 /** 1084 * getVideoQuality 1085 * @returns {jQuery.mbYTPlayer} 1086 */ 1087 getVideoQuality: function () { 1088 let YTPlayer = this.get(0); 1089 let quality = YTPlayer.player.getPlaybackQuality(); 1090 return quality 1091 }, 1092 1093 /** 1094 * playlist 1095 * @param videos -> Array or String (videoList ID) 1096 * @param shuffle 1097 * @param callback 1098 * @returns {jQuery.mbYTPlayer} 1099 * 1100 * To retrieve a Youtube playlist the Youtube API key is required: 1101 * https://console.developers.google.com/ 1102 * jQuery.mbYTPlayer.apiKey 1103 */ 1104 playlist: function (videos, shuffle, callback) { 1105 1106 let $YTPlayer = this; 1107 let YTPlayer = $YTPlayer.get(0); 1108 1109 YTPlayer.isList = true; 1110 1111 if (shuffle) 1112 videos = jQuery.shuffle(videos); 1113 1114 if (!YTPlayer.videoID) { 1115 YTPlayer.videos = videos; 1116 YTPlayer.videoCounter = 1; 1117 YTPlayer.videoLength = videos.length; 1118 jQuery(YTPlayer).data('property', videos[0]); 1119 jQuery(YTPlayer).YTPlayer() 1120 } 1121 1122 if (typeof callback == 'function') 1123 jQuery(YTPlayer).on('YTPChanged', function () { 1124 callback(YTPlayer) 1125 }); 1126 1127 jQuery(YTPlayer).on('YTPEnd', function () { 1128 jQuery(YTPlayer).YTPPlayNext() 1129 }); 1130 return this 1131 }, 1132 1133 /** 1134 * playNext 1135 * @returns {jQuery.mbYTPlayer} 1136 */ 1137 playNext: function () { 1138 let YTPlayer = this.get(0); 1139 YTPlayer.videoCounter++; 1140 if (YTPlayer.videoCounter > YTPlayer.videoLength) 1141 YTPlayer.videoCounter = 1; 1142 jQuery(YTPlayer).YTPPlayIndex(YTPlayer.videoCounter); 1143 return this 1144 }, 1145 1146 /** 1147 * playPrev 1148 * @returns {jQuery.mbYTPlayer} 1149 */ 1150 playPrev: function () { 1151 let YTPlayer = this.get(0); 1152 YTPlayer.videoCounter--; 1153 if (YTPlayer.videoCounter <= 0) 1154 YTPlayer.videoCounter = YTPlayer.videoLength; 1155 jQuery(YTPlayer).YTPPlayIndex(YTPlayer.videoCounter); 1156 return this 1157 }, 1158 1159 /** 1160 * playIndex 1161 * @param idx 1162 * @returns {jQuery.mbYTPlayer} 1163 */ 1164 playIndex: function (idx) { 1165 let YTPlayer = this.get(0); 1166 if (YTPlayer.checkForStartAt) { 1167 clearInterval(YTPlayer.checkForStartAt); 1168 clearInterval(YTPlayer.getState) 1169 } 1170 YTPlayer.videoCounter = idx; 1171 1172 if (YTPlayer.videoCounter >= YTPlayer.videoLength) 1173 YTPlayer.videoCounter = YTPlayer.videoLength; 1174 1175 let video = YTPlayer.videos[YTPlayer.videoCounter - 1]; 1176 1177 jQuery(YTPlayer).YTPChangeVideo(video); 1178 return this 1179 }, 1180 1181 /** 1182 * changeVideo 1183 * @param opt 1184 * @returns {jQuery.mbYTPlayer} 1185 */ 1186 changeVideo: function (opt) { 1187 let $YTPlayer = this; 1188 let YTPlayer = $YTPlayer.get(0); 1189 1190 YTPlayer.opt.startAt = 0; 1191 YTPlayer.opt.stopAt = 0; 1192 YTPlayer.opt.mask = false; 1193 YTPlayer.opt.mute = true; 1194 YTPlayer.opt.autoPlay = true; 1195 YTPlayer.opt.addFilters = false; 1196 YTPlayer.opt.coverImage = false; 1197 1198 YTPlayer.hasData = false; 1199 YTPlayer.hasChanged = true; 1200 1201 YTPlayer.player.loopTime = undefined; 1202 1203 if (opt) 1204 jQuery.extend(YTPlayer.opt, opt); 1205 1206 YTPlayer.videoID = getYTPVideoID(YTPlayer.opt.videoURL).videoID; 1207 1208 if (YTPlayer.opt.loop && typeof YTPlayer.opt.loop == 'boolean') 1209 YTPlayer.opt.loop = 9999; 1210 1211 YTPlayer.wrapper.css({ 1212 background: 'none' 1213 }); 1214 1215 jQuery(YTPlayer.playerEl).CSSAnimate({ 1216 opacity: 0 1217 }, YTPlayer.opt.fadeOnStartTime, function () { 1218 1219 jQuery.mbYTPlayer.getDataFromAPI(YTPlayer); 1220 1221 $YTPlayer.YTPGetPlayer().loadVideoById({ 1222 videoId : YTPlayer.videoID, 1223 suggestedQuality: YTPlayer.opt.quality 1224 }); 1225 1226 $YTPlayer.YTPPause(); 1227 $YTPlayer.optimizeDisplay(); 1228 1229 if (YTPlayer.checkForStartAt) { 1230 clearInterval(YTPlayer.checkForStartAt); 1231 clearInterval(YTPlayer.getState) 1232 } 1233 $YTPlayer.YTPCheckForState() 1234 }); 1235 1236 let YTPChangeVideo = jQuery.Event('YTPChangeVideo'); 1237 YTPChangeVideo.time = YTPlayer.currentTime; 1238 jQuery(YTPlayer).trigger(YTPChangeVideo); 1239 1240 jQuery.mbYTPlayer.applyMask(YTPlayer); 1241 1242 return this 1243 }, 1244 1245 /** 1246 * getPlayer 1247 * @returns {player} 1248 */ 1249 getPlayer: function () { 1250 let YTPlayer = this.get(0); 1251 return !YTPlayer.isReady ? null : YTPlayer.player 1252 }, 1253 1254 /** 1255 * playerDestroy 1256 * @returns {jQuery.mbYTPlayer} 1257 */ 1258 playerDestroy: function () { 1259 let YTPlayer = this.get(0); 1260 1261 if (!YTPlayer.isReady) 1262 return this; 1263 1264 ytp.YTAPIReady = true; 1265 ytp.backgroundIsInited = false; 1266 YTPlayer.isInit = false; 1267 YTPlayer.videoID = null; 1268 YTPlayer.isReady = false; 1269 YTPlayer.wrapper.remove(); 1270 jQuery('#controlBar_' + YTPlayer.id).remove(); 1271 clearInterval(YTPlayer.checkForStartAt); 1272 clearInterval(YTPlayer.getState); 1273 return this 1274 }, 1275 1276 /** 1277 * fullscreen 1278 * @param real 1279 * @returns {jQuery.mbYTPlayer} 1280 */ 1281 fullscreen: function (real) { 1282 let YTPlayer = this.get(0); 1283 1284 if (typeof real == 'undefined') 1285 real = eval(YTPlayer.opt.realFullscreen); 1286 1287 let controls = jQuery('#controlBar_' + YTPlayer.id); 1288 let fullScreenBtn = controls.find('.mb_OnlyYT'); 1289 let videoWrapper = YTPlayer.isPlayer ? YTPlayer.opt.containment : YTPlayer.wrapper; 1290 1291 if (real) { 1292 let fullscreenchange = jQuery.mbBrowser.mozilla ? 'mozfullscreenchange' : jQuery.mbBrowser.webkit ? 'webkitfullscreenchange' : 'fullscreenchange'; 1293 jQuery(document).off(fullscreenchange).on(fullscreenchange, function () { 1294 let isFullScreen = RunPrefixMethod(document, 'IsFullScreen') || RunPrefixMethod(document, 'FullScreen'); 1295 if (!isFullScreen) { 1296 YTPlayer.isAlone = false; 1297 fullScreenBtn.html(jQuery.mbYTPlayer.controls.onlyYT); 1298 jQuery(YTPlayer).YTPSetVideoQuality(YTPlayer.opt.quality); 1299 videoWrapper.removeClass('YTPFullscreen'); 1300 videoWrapper.CSSAnimate({ 1301 opacity: YTPlayer.opt.opacity 1302 }, YTPlayer.opt.fadeOnStartTime); 1303 1304 videoWrapper.css({ 1305 zIndex: 0 1306 }); 1307 1308 if (YTPlayer.isBackground) { 1309 jQuery('body').after(controls) 1310 } else { 1311 YTPlayer.wrapper.before(controls) 1312 } 1313 jQuery(window).resize(); 1314 jQuery(YTPlayer).trigger('YTPFullScreenEnd') 1315 1316 } else { 1317 jQuery(YTPlayer).trigger('YTPFullScreenStart') 1318 } 1319 }) 1320 } 1321 if (!YTPlayer.isAlone) { 1322 function hideMouse() { 1323 YTPlayer.overlay.css({ 1324 cursor: 'none' 1325 }) 1326 } 1327 1328 jQuery(document).on('mousemove.YTPlayer', function (e) { 1329 YTPlayer.overlay.css({ 1330 cursor: 'auto' 1331 }); 1332 clearTimeout(YTPlayer.hideCursor); 1333 if (!jQuery(e.target).parents().is('.mb_YTPBar')) 1334 YTPlayer.hideCursor = setTimeout(hideMouse, 3000) 1335 }); 1336 1337 hideMouse(); 1338 1339 if (real) { 1340 videoWrapper.css({ 1341 opacity: 0 1342 }); 1343 videoWrapper.addClass('YTPFullscreen'); 1344 launchFullscreen(videoWrapper.get(0)); 1345 1346 setTimeout(function () { 1347 videoWrapper.CSSAnimate({ 1348 opacity: 1 1349 }, YTPlayer.opt.fadeOnStartTime * 2); 1350 1351 videoWrapper.append(controls); 1352 jQuery(YTPlayer).optimizeDisplay(); 1353 YTPlayer.player.seekTo(YTPlayer.player.getCurrentTime() + .1, true) 1354 1355 }, YTPlayer.opt.fadeOnStartTime) 1356 } else 1357 videoWrapper.css({ 1358 zIndex: 10000 1359 }).CSSAnimate({ 1360 opacity: 1 1361 }, YTPlayer.opt.fadeOnStartTime * 2); 1362 fullScreenBtn.html(jQuery.mbYTPlayer.controls.showSite); 1363 YTPlayer.isAlone = true 1364 } else { 1365 jQuery(document).off('mousemove.YTPlayer'); 1366 clearTimeout(YTPlayer.hideCursor); 1367 YTPlayer.overlay.css({ 1368 cursor: 'auto' 1369 }); 1370 if (real) { 1371 cancelFullscreen() 1372 } else { 1373 videoWrapper.CSSAnimate({ 1374 opacity: YTPlayer.opt.opacity 1375 }, YTPlayer.opt.fadeOnStartTime); 1376 videoWrapper.css({ 1377 zIndex: 0 1378 }) 1379 } 1380 fullScreenBtn.html(jQuery.mbYTPlayer.controls.onlyYT); 1381 YTPlayer.isAlone = false 1382 } 1383 1384 function RunPrefixMethod(obj, method) { 1385 let pfx = ['webkit', 'moz', 'ms', 'o', '']; 1386 let p = 0, 1387 m, t; 1388 while (p < pfx.length && !obj[m]) { 1389 m = method; 1390 if (pfx[p] === '') { 1391 m = m.substr(0, 1).toLowerCase() + m.substr(1) 1392 } 1393 m = pfx[p] + m; 1394 t = typeof obj[m]; 1395 if (t != 'undefined') { 1396 pfx = [pfx[p]]; 1397 return (t == 'function' ? obj[m]() : obj[m]) 1398 } 1399 p++ 1400 } 1401 } 1402 1403 function launchFullscreen(element) { 1404 RunPrefixMethod(element, 'RequestFullScreen') 1405 } 1406 1407 function cancelFullscreen() { 1408 if (RunPrefixMethod(document, 'FullScreen') || RunPrefixMethod(document, 'IsFullScreen')) { 1409 RunPrefixMethod(document, 'CancelFullScreen') 1410 } 1411 } 1412 1413 return this 1414 }, 1415 1416 /** 1417 * toggleLoops 1418 * @returns {jQuery.mbYTPlayer} 1419 */ 1420 toggleLoops: function () { 1421 let YTPlayer = this.get(0); 1422 let data = YTPlayer.opt; 1423 if (data.loop == 1) { 1424 data.loop = 0 1425 } else { 1426 if (data.startAt) { 1427 YTPlayer.player.seekTo(data.startAt) 1428 } else { 1429 YTPlayer.player.playVideo() 1430 } 1431 data.loop = 1 1432 } 1433 return this 1434 }, 1435 1436 /** 1437 * play 1438 * @returns {jQuery.mbYTPlayer} 1439 */ 1440 play: function () { 1441 let YTPlayer = this.get(0); 1442 let $YTPlayer = jQuery(YTPlayer); 1443 1444 if (!YTPlayer.isReady) 1445 return this; 1446 1447 setTimeout(function () { 1448 $YTPlayer.YTPSetAbundance(YTPlayer.opt.abundance) 1449 }, 300); 1450 1451 YTPlayer.player.playVideo(); 1452 1453 jQuery(YTPlayer.playerEl).css({ 1454 opacity: 1 1455 }); 1456 1457 YTPlayer.wrapper.css({ 1458 backgroundImage: 'none' 1459 }); 1460 1461 YTPlayer.wrapper.CSSAnimate({ 1462 opacity: YTPlayer.isAlone ? 1 : YTPlayer.opt.opacity 1463 }, YTPlayer.opt.fadeOnStartTime); 1464 1465 let controls = jQuery('#controlBar_' + YTPlayer.id); 1466 let playBtn = controls.find('.mb_YTPPlayPause'); 1467 playBtn.html(jQuery.mbYTPlayer.controls.pause); 1468 YTPlayer.state = 1; 1469 1470 return this 1471 }, 1472 1473 /** 1474 * togglePlay 1475 * @param callback 1476 * @returns {jQuery.mbYTPlayer} 1477 */ 1478 togglePlay: function (callback) { 1479 let YTPlayer = this.get(0); 1480 1481 if (!YTPlayer.isReady) 1482 return this; 1483 1484 if (YTPlayer.state === 1) 1485 this.YTPPause(); 1486 else 1487 this.YTPPlay(); 1488 1489 if (typeof callback == 'function') 1490 callback(YTPlayer.state); 1491 1492 return this 1493 }, 1494 1495 /** 1496 * stop 1497 * @returns {jQuery.mbYTPlayer} 1498 */ 1499 stop: function () { 1500 let YTPlayer = this.get(0); 1501 1502 if (!YTPlayer.isReady) 1503 return this; 1504 1505 let controls = jQuery('#controlBar_' + YTPlayer.id); 1506 let playBtn = controls.find('.mb_YTPPlayPause'); 1507 playBtn.html(jQuery.mbYTPlayer.controls.play); 1508 YTPlayer.player.stopVideo(); 1509 return this 1510 }, 1511 1512 /** 1513 * pause 1514 * @returns {jQuery.mbYTPlayer} 1515 */ 1516 pause: function () { 1517 let YTPlayer = this.get(0); 1518 1519 if (!YTPlayer.isReady) 1520 return this; 1521 1522 if (YTPlayer.opt.abundance < .2) 1523 this.YTPSetAbundance(.2); 1524 1525 YTPlayer.player.pauseVideo(); 1526 YTPlayer.state = 2; 1527 return this 1528 }, 1529 1530 /** 1531 * seekTo 1532 * @param sec 1533 * @returns {jQuery.mbYTPlayer} 1534 */ 1535 seekTo: function (sec) { 1536 let YTPlayer = this.get(0); 1537 1538 if (!YTPlayer.isReady) 1539 return this; 1540 1541 YTPlayer.player.seekTo(sec, true); 1542 return this 1543 }, 1544 1545 /** 1546 * 1547 * @returns {*} 1548 */ 1549 getPlaybackRate: function () { 1550 let YTPlayer = this.get(0); 1551 1552 if (!YTPlayer.isReady) 1553 return this; 1554 1555 return YTPlayer.player.getPlaybackRate() 1556 }, 1557 1558 /** 1559 * setPlaybackRate 1560 * @param val:Number 1561 * 0.25, 0.5, 1, 1.5, 2 1562 * @returns {jQuery.mbYTPlayer} 1563 */ 1564 setPlaybackRate: function (val) { 1565 let YTPlayer = this.get(0); 1566 1567 if (!YTPlayer.isReady) 1568 return this; 1569 1570 YTPlayer.player.setPlaybackRate(val); 1571 return this 1572 }, 1573 1574 /** 1575 * setVolume 1576 * @param val 1577 * @returns {jQuery.mbYTPlayer} 1578 */ 1579 setVolume: function (val) { 1580 let YTPlayer = this.get(0); 1581 1582 if (!YTPlayer.isReady) 1583 return this; 1584 1585 YTPlayer.opt.vol = val; 1586 this.YTPUnmute(); 1587 YTPlayer.player.setVolume(YTPlayer.opt.vol); 1588 1589 if (YTPlayer.volumeBar && YTPlayer.volumeBar.length) 1590 YTPlayer.volumeBar.updateSliderVal(val); 1591 1592 return this 1593 }, 1594 /** 1595 * getVolume 1596 * @returns {*} 1597 */ 1598 getVolume: function () { 1599 let YTPlayer = this.get(0); 1600 1601 if (!YTPlayer.isReady) 1602 return this; 1603 1604 return YTPlayer.player.getVolume() 1605 }, 1606 1607 /** 1608 * toggleVolume 1609 * @returns {jQuery.mbYTPlayer} 1610 */ 1611 toggleVolume: function () { 1612 1613 let YTPlayer = this.get(0); 1614 1615 if (!YTPlayer.isReady) 1616 return this; 1617 1618 if (YTPlayer.isMute) { 1619 if (!jQuery.mbBrowser.mobile) 1620 this.YTPSetVolume(YTPlayer.opt.vol); 1621 this.YTPUnmute() 1622 } else { 1623 this.YTPMute() 1624 } 1625 return this 1626 }, 1627 1628 /** 1629 * mute 1630 * @returns {jQuery.mbYTPlayer} 1631 */ 1632 mute: function () { 1633 let YTPlayer = this.get(0); 1634 1635 if (!YTPlayer.isReady) 1636 return this; 1637 1638 if (YTPlayer.isMute) 1639 return this; 1640 YTPlayer.player.mute(); 1641 YTPlayer.isMute = true; 1642 YTPlayer.player.setVolume(0); 1643 if (YTPlayer.volumeBar && YTPlayer.volumeBar.length && YTPlayer.volumeBar.width() > 10) { 1644 YTPlayer.volumeBar.updateSliderVal(0) 1645 } 1646 let controls = jQuery('#controlBar_' + YTPlayer.id); 1647 let muteBtn = controls.find('.mb_YTPMuteUnmute'); 1648 muteBtn.html(jQuery.mbYTPlayer.controls.unmute); 1649 jQuery(YTPlayer).addClass('isMuted'); 1650 if (YTPlayer.volumeBar && YTPlayer.volumeBar.length) YTPlayer.volumeBar.addClass('muted'); 1651 let YTPEvent = jQuery.Event('YTPMuted'); 1652 YTPEvent.time = YTPlayer.currentTime; 1653 1654 if (!YTPlayer.preventTrigger) 1655 jQuery(YTPlayer).trigger(YTPEvent); 1656 1657 return this 1658 }, 1659 1660 /** 1661 * unmute 1662 * @returns {jQuery.mbYTPlayer} 1663 */ 1664 unmute: function () { 1665 let YTPlayer = this.get(0); 1666 1667 if (!YTPlayer.isReady) 1668 return this; 1669 1670 if (!YTPlayer.isMute) 1671 return this; 1672 1673 YTPlayer.player.unMute(); 1674 YTPlayer.isMute = false; 1675 jQuery(YTPlayer).YTPSetVolume(YTPlayer.opt.vol); 1676 if (YTPlayer.volumeBar && YTPlayer.volumeBar.length) 1677 YTPlayer.volumeBar.updateSliderVal(YTPlayer.opt.vol > 10 ? YTPlayer.opt.vol : 10); 1678 let controls = jQuery('#controlBar_' + YTPlayer.id); 1679 let muteBtn = controls.find('.mb_YTPMuteUnmute'); 1680 muteBtn.html(jQuery.mbYTPlayer.controls.mute); 1681 jQuery(YTPlayer).removeClass('isMuted'); 1682 if (YTPlayer.volumeBar && YTPlayer.volumeBar.length) 1683 YTPlayer.volumeBar.removeClass('muted'); 1684 let YTPEvent = jQuery.Event('YTPUnmuted'); 1685 YTPEvent.time = YTPlayer.currentTime; 1686 1687 if (!YTPlayer.preventTrigger) 1688 jQuery(YTPlayer).trigger(YTPEvent); 1689 1690 return this 1691 }, 1692 1693 /* FILTERS ---------------------------------------------------------------------------------------------------------*/ 1694 1695 /** 1696 * applyFilter 1697 * @param filter 1698 * @param value 1699 * @returns {jQuery.mbYTPlayer} 1700 */ 1701 applyFilter: function (filter, value) { 1702 let $YTPlayer = this; 1703 let YTPlayer = $YTPlayer.get(0); 1704 1705 if (!YTPlayer.isReady) 1706 return this; 1707 1708 YTPlayer.filters[filter].value = value; 1709 if (YTPlayer.filtersEnabled) 1710 $YTPlayer.YTPEnableFilters() 1711 }, 1712 1713 /** 1714 * applyFilters 1715 * @param filters 1716 * @returns {jQuery.mbYTPlayer} 1717 */ 1718 applyFilters: function (filters) { 1719 let $YTPlayer = this; 1720 let YTPlayer = $YTPlayer.get(0); 1721 1722 if (!YTPlayer.isReady) { 1723 jQuery(YTPlayer).on('YTPReady', function () { 1724 $YTPlayer.YTPApplyFilters(filters) 1725 }); 1726 return this 1727 } 1728 1729 for (let key in filters) { 1730 $YTPlayer.YTPApplyFilter(key, filters[key]) 1731 } 1732 1733 $YTPlayer.trigger('YTPFiltersApplied') 1734 }, 1735 1736 /** 1737 * toggleFilter 1738 * @param filter 1739 * @param value 1740 * @returns {jQuery.mbYTPlayer} 1741 */ 1742 toggleFilter: function (filter, value) { 1743 let $YTPlayer = this; 1744 let YTPlayer = $YTPlayer.get(0); 1745 1746 if (!YTPlayer.isReady) 1747 return this; 1748 1749 if (!YTPlayer.filters[filter].value) 1750 YTPlayer.filters[filter].value = value; 1751 else 1752 YTPlayer.filters[filter].value = 0; 1753 1754 if (YTPlayer.filtersEnabled) 1755 jQuery(YTPlayer).YTPEnableFilters(); 1756 1757 return this 1758 }, 1759 1760 /** 1761 * toggleFilters 1762 * @param callback 1763 * @returns {jQuery.mbYTPlayer} 1764 */ 1765 toggleFilters: function (callback) { 1766 let $YTPlayer = this; 1767 let YTPlayer = $YTPlayer.get(0); 1768 1769 if (!YTPlayer.isReady) 1770 return this; 1771 1772 if (YTPlayer.filtersEnabled) { 1773 jQuery(YTPlayer).trigger('YTPDisableFilters'); 1774 jQuery(YTPlayer).YTPDisableFilters() 1775 } else { 1776 jQuery(YTPlayer).YTPEnableFilters(); 1777 jQuery(YTPlayer).trigger('YTPEnableFilters') 1778 } 1779 if (typeof callback == 'function') 1780 callback(YTPlayer.filtersEnabled); 1781 1782 return this 1783 }, 1784 1785 /** 1786 * disableFilters 1787 * @returns {jQuery.mbYTPlayer} 1788 */ 1789 disableFilters: function () { 1790 let $YTPlayer = this; 1791 let YTPlayer = $YTPlayer.get(0); 1792 1793 if (!YTPlayer.isReady) 1794 return this; 1795 1796 let iframe = jQuery(YTPlayer.playerEl); 1797 iframe.css('-webkit-filter', ''); 1798 iframe.css('filter', ''); 1799 YTPlayer.filtersEnabled = false; 1800 1801 return this 1802 }, 1803 1804 /** 1805 * enableFilters 1806 * @returns {jQuery.mbYTPlayer} 1807 */ 1808 enableFilters: function () { 1809 let $YTPlayer = this; 1810 let YTPlayer = $YTPlayer.get(0); 1811 1812 if (!YTPlayer.isReady) 1813 return this; 1814 1815 let iframe = jQuery(YTPlayer.playerEl); 1816 let filterStyle = ''; 1817 for (let key in YTPlayer.filters) { 1818 if (YTPlayer.filters[key].value) 1819 filterStyle += key.replace('_', '-') + '(' + YTPlayer.filters[key].value + YTPlayer.filters[key].unit + ') ' 1820 } 1821 iframe.css('-webkit-filter', filterStyle); 1822 iframe.css('filter', filterStyle); 1823 YTPlayer.filtersEnabled = true; 1824 1825 return this 1826 }, 1827 1828 /** 1829 * removeFilter 1830 * @param filter 1831 * @param callback 1832 * @returns {jQuery.mbYTPlayer} 1833 */ 1834 removeFilter: function (filter, callback) { 1835 let $YTPlayer = this; 1836 let YTPlayer = $YTPlayer.get(0); 1837 1838 if (!YTPlayer.isReady) 1839 return this; 1840 1841 if (typeof filter == 'function') { 1842 callback = filter; 1843 filter = null 1844 } 1845 1846 if (!filter) { 1847 for (let key in YTPlayer.filters) { 1848 if (YTPlayer.filters.hasOwnProperty(key)) { 1849 $YTPlayer.YTPApplyFilter(key, 0); 1850 if (typeof callback == 'function') 1851 callback(key); 1852 } 1853 } 1854 1855 YTPlayer.filters = jQuery.extend(true, {}, jQuery.mbYTPlayer.defaultFilters) 1856 1857 } else { 1858 $YTPlayer.YTPApplyFilter(filter, 0); 1859 if (typeof callback == 'function') callback(filter) 1860 } 1861 1862 let YTPEvent = jQuery.Event('YTPFiltersApplied'); 1863 $YTPlayer.trigger(YTPEvent); 1864 1865 return this 1866 }, 1867 1868 /** 1869 * getFilters 1870 * @returns {filters} 1871 */ 1872 getFilters: function () { 1873 let YTPlayer = this.get(0); 1874 1875 if (!YTPlayer.isReady) 1876 return this; 1877 1878 return YTPlayer.filters 1879 }, 1880 1881 /* MASK ---------------------------------------------------------------------------------------------------------*/ 1882 1883 /** 1884 * addMask 1885 * @param mask 1886 * @returns {jQuery.mbYTPlayer} 1887 */ 1888 addMask: function (mask) { 1889 let YTPlayer = this.get(0); 1890 1891 if (!mask) 1892 mask = YTPlayer.actualMask; 1893 1894 let tempImg = jQuery('<img/>').attr('src', mask).on('load', function () { 1895 YTPlayer.overlay.CSSAnimate({ 1896 opacity: 0 1897 }, YTPlayer.opt.fadeOnStartTime, function () { 1898 YTPlayer.hasMask = true; 1899 tempImg.remove(); 1900 YTPlayer.overlay.css({ 1901 backgroundImage : 'url(' + mask + ')', 1902 backgroundRepeat : 'no-repeat', 1903 backgroundPosition: 'center center', 1904 backgroundSize : 'cover' 1905 }); 1906 YTPlayer.overlay.CSSAnimate({ 1907 opacity: 1 1908 }, YTPlayer.opt.fadeOnStartTime) 1909 }) 1910 }); 1911 1912 return this 1913 }, 1914 1915 /** 1916 * removeMask 1917 * @returns {jQuery.mbYTPlayer} 1918 */ 1919 removeMask: function () { 1920 let YTPlayer = this.get(0); 1921 1922 YTPlayer.overlay.CSSAnimate({ 1923 opacity: 0 1924 }, YTPlayer.opt.fadeOnStartTime, function () { 1925 YTPlayer.hasMask = false; 1926 YTPlayer.overlay.css({ 1927 backgroundImage : '', 1928 backgroundRepeat : '', 1929 backgroundPosition: '', 1930 backgroundSize : '' 1931 }); 1932 YTPlayer.overlay.CSSAnimate({ 1933 opacity: 1 1934 }, YTPlayer.opt.fadeOnStartTime) 1935 }); 1936 1937 return this 1938 }, 1939 1940 /** 1941 * Apply mask 1942 * @param YTPlayer 1943 */ 1944 applyMask: function (YTPlayer) { 1945 let $YTPlayer = jQuery(YTPlayer); 1946 1947 $YTPlayer.off('YTPTime.mask'); 1948 1949 if (YTPlayer.opt.mask) { 1950 if (typeof YTPlayer.opt.mask == 'string') { 1951 1952 $YTPlayer.YTPAddMask(YTPlayer.opt.mask); 1953 YTPlayer.actualMask = YTPlayer.opt.mask 1954 1955 } else if (typeof YTPlayer.opt.mask == 'object') { 1956 1957 for (let time in YTPlayer.opt.mask) { 1958 1959 if (YTPlayer.opt.mask[time]) 1960 img = jQuery('<img/>').attr('src', YTPlayer.opt.mask[time]) 1961 } 1962 1963 if (YTPlayer.opt.mask[0]) 1964 $YTPlayer.YTPAddMask(YTPlayer.opt.mask[0]); 1965 1966 $YTPlayer.on('YTPTime.mask', function (e) { 1967 1968 for (let time in YTPlayer.opt.mask) { 1969 if (e.time === time) 1970 if (!YTPlayer.opt.mask[time]) { 1971 $YTPlayer.YTPRemoveMask() 1972 } else { 1973 $YTPlayer.YTPAddMask(YTPlayer.opt.mask[time]); 1974 YTPlayer.actualMask = YTPlayer.opt.mask[time] 1975 } 1976 } 1977 }) 1978 } 1979 } 1980 }, 1981 1982 /** 1983 * toggleMask 1984 * @returns {jQuery.mbYTPlayer} 1985 */ 1986 toggleMask: function () { 1987 let YTPlayer = this.get(0); 1988 1989 let $YTPlayer = jQuery(YTPlayer); 1990 if (YTPlayer.hasMask) 1991 $YTPlayer.YTPRemoveMask(); 1992 else 1993 $YTPlayer.YTPAddMask(); 1994 return this 1995 }, 1996 1997 /* CONTROLS --------------------------------------------------------------------------------------------------------*/ 1998 1999 /** 2000 * manageProgress 2001 * @returns {{totalTime: number, currentTime: number}} 2002 */ 2003 manageProgress: function () { 2004 let YTPlayer = this.get(0); 2005 let controls = jQuery('#controlBar_' + YTPlayer.id); 2006 let progressBar = controls.find('.mb_YTPProgress'); 2007 let loadedBar = controls.find('.mb_YTPLoaded'); 2008 let timeBar = controls.find('.mb_YTPseekbar'); 2009 let totW = progressBar.outerWidth(); 2010 let currentTime = Math.floor(YTPlayer.player.getCurrentTime()); 2011 let totalTime = Math.floor(YTPlayer.player.getDuration()); 2012 let timeW = (currentTime * totW) / totalTime; 2013 let startLeft = 0; 2014 let loadedW = YTPlayer.player.getVideoLoadedFraction() * 100; 2015 loadedBar.css({ 2016 left : startLeft, 2017 width: loadedW + '%' 2018 }); 2019 timeBar.css({ 2020 left : 0, 2021 width: timeW 2022 }); 2023 return { 2024 totalTime : totalTime, 2025 currentTime: currentTime 2026 } 2027 }, 2028 2029 /** 2030 * buildControls 2031 * @param YTPlayer 2032 */ 2033 buildControls: function (YTPlayer) { 2034 2035 jQuery('#controlBar_' + YTPlayer.id).remove(); 2036 if (!YTPlayer.opt.showControls) { 2037 YTPlayer.controlBar = false; 2038 return 2039 } 2040 2041 YTPlayer.opt.showYTLogo = YTPlayer.opt.showYTLogo || YTPlayer.opt.printUrl; 2042 if (jQuery('#controlBar_' + YTPlayer.id).length) 2043 return; 2044 YTPlayer.controlBar = jQuery('<div/>').attr('id', 'controlBar_' + YTPlayer.id).addClass('mb_YTPBar').css({ 2045 whiteSpace: 'noWrap', 2046 position : YTPlayer.isBackground ? 'fixed' : 'absolute', 2047 zIndex : YTPlayer.isBackground ? 10000 : 1000 2048 }).hide().on('click', function (e) { 2049 e.stopPropagation() 2050 }); 2051 let buttonBar = jQuery('<div/>').addClass('buttonBar'); 2052 /** 2053 * play/pause button 2054 * */ 2055 let playpause = jQuery('<span>' + jQuery.mbYTPlayer.controls.play + '</span>').addClass('mb_YTPPlayPause ytpicon').on('click', function (e) { 2056 e.stopPropagation(); 2057 jQuery(YTPlayer).YTPTogglePlay() 2058 }); 2059 /** 2060 * mute/unmute button 2061 * */ 2062 let MuteUnmute = jQuery('<span>' + jQuery.mbYTPlayer.controls.mute + '</span>').addClass('mb_YTPMuteUnmute ytpicon').on('click', function (e) { 2063 e.stopPropagation(); 2064 jQuery(YTPlayer).YTPToggleVolume() 2065 }); 2066 /** 2067 * volume bar 2068 * */ 2069 let volumeBar = jQuery('<div/>').addClass('mb_YTPVolumeBar').css({ 2070 display: 'inline-block' 2071 }); 2072 YTPlayer.volumeBar = volumeBar; 2073 2074 /** 2075 * time elapsed 2076 * */ 2077 let idx = jQuery('<span/>').addClass('mb_YTPTime'); 2078 let vURL = YTPlayer.opt.videoURL ? YTPlayer.opt.videoURL : ''; 2079 if (vURL.indexOf('http') < 0) vURL = 'https://www.youtube.com/watch?v=' + YTPlayer.opt.videoURL; 2080 let movieUrl = jQuery('<span/>').html(jQuery.mbYTPlayer.controls.ytLogo).addClass('mb_YTPUrl ytpicon').attr('title', 'view on YouTube').on('click', function () { 2081 window.open(vURL, 'viewOnYT') 2082 }); 2083 let onlyVideo = jQuery('<span/>').html(jQuery.mbYTPlayer.controls.onlyYT).addClass('mb_OnlyYT ytpicon').on('click', function (e) { 2084 e.stopPropagation(); 2085 jQuery(YTPlayer).YTPFullscreen(YTPlayer.opt.realFullscreen) 2086 }); 2087 let progressBar = jQuery('<div/>').addClass('mb_YTPProgress').css('position', 'absolute').on('click', function (e) { 2088 e.stopPropagation(); 2089 timeBar.css({ 2090 width: (e.clientX - timeBar.offset().left) 2091 }); 2092 YTPlayer.timeW = e.clientX - timeBar.offset().left; 2093 YTPlayer.controlBar.find('.mb_YTPLoaded').css({ 2094 width: 0 2095 }); 2096 let totalTime = Math.floor(YTPlayer.player.getDuration()); 2097 YTPlayer.goto = (timeBar.outerWidth() * totalTime) / progressBar.outerWidth(); 2098 YTPlayer.player.seekTo(parseFloat(YTPlayer.goto), true); 2099 YTPlayer.controlBar.find('.mb_YTPLoaded').css({ 2100 width: 0 2101 }) 2102 }); 2103 let loadedBar = jQuery('<div/>').addClass('mb_YTPLoaded').css('position', 'absolute'); 2104 let timeBar = jQuery('<div/>').addClass('mb_YTPseekbar').css('position', 'absolute'); 2105 progressBar.append(loadedBar).append(timeBar); 2106 buttonBar.append(playpause).append(MuteUnmute).append(volumeBar).append(idx); 2107 2108 if (YTPlayer.opt.showYTLogo) { 2109 buttonBar.append(movieUrl) 2110 } 2111 2112 /** 2113 * Full screen button 2114 */ 2115 if (YTPlayer.isBackground || (eval(YTPlayer.opt.realFullscreen) && !YTPlayer.isBackground)) 2116 buttonBar.append(onlyVideo); 2117 2118 YTPlayer.controlBar.append(buttonBar).append(progressBar); 2119 2120 if (!YTPlayer.isBackground) { 2121 YTPlayer.controlBar.addClass('inlinePlayer'); 2122 YTPlayer.wrapper.before(YTPlayer.controlBar) 2123 } else { 2124 jQuery('body').after(YTPlayer.controlBar) 2125 } 2126 2127 /** 2128 * Volume slider 2129 */ 2130 volumeBar.simpleSlider({ 2131 initialval : YTPlayer.opt.vol, 2132 scale : 100, 2133 orientation: 'h', 2134 callback : function (el) { 2135 2136 if (el.value == 0) { 2137 jQuery(YTPlayer).YTPMute() 2138 } else { 2139 jQuery(YTPlayer).YTPUnmute() 2140 } 2141 YTPlayer.player.setVolume(el.value); 2142 if (!YTPlayer.isMute) 2143 YTPlayer.opt.vol = el.value 2144 } 2145 2146 }) 2147 }, 2148 2149 /** 2150 * changeCoverImage 2151 * 2152 * @param imageURL 2153 * @returns {jQuery.mbYTPlayer} 2154 */ 2155 changeCoverImage: function (imageURL) { 2156 let YTPlayer = this.get(0); 2157 if (YTPlayer.opt.coverImage || YTPlayer.orig_containment_background) { 2158 let bgndURL = imageURL || (YTPlayer.opt.coverImage ? 'url(' + YTPlayer.opt.coverImage + ') center center' : YTPlayer.orig_containment_background); 2159 if (bgndURL) 2160 YTPlayer.opt.containment.css({ 2161 background : bgndURL, 2162 backgroundSize : 'cover', 2163 backgroundRepeat : 'no-repeat', 2164 backgroundAttachment: 'fixed' 2165 }) 2166 } 2167 return this; 2168 }, 2169 2170 /* MANAGE PLAYER STATE ------------------------------------------------------------------------------------------*/ 2171 2172 /** 2173 * checkForState 2174 */ 2175 checkForState: function () { 2176 let YTPlayer = this.get(0); 2177 let $YTPlayer = jQuery(YTPlayer); 2178 2179 clearInterval(YTPlayer.getState); 2180 let interval = 100; 2181 //Checking if player has been removed from the scene 2182 if (!jQuery.contains(document, YTPlayer)) { 2183 $YTPlayer.YTPPlayerDestroy(); 2184 clearInterval(YTPlayer.getState); 2185 clearInterval(YTPlayer.checkForStartAt); 2186 return 2187 } 2188 2189 jQuery.mbYTPlayer.checkForStart(YTPlayer); 2190 2191 YTPlayer.getState = setInterval(function () { 2192 let $YTPlayer = jQuery(YTPlayer); 2193 2194 if (!YTPlayer.isReady) 2195 return; 2196 2197 let prog = jQuery(YTPlayer).YTPManageProgress(); 2198 2199 let stopAt = YTPlayer.opt.stopAt > YTPlayer.opt.startAt ? YTPlayer.opt.stopAt : 0; 2200 stopAt = stopAt < YTPlayer.player.getDuration() ? stopAt : 0; 2201 2202 if (YTPlayer.currentTime != prog.currentTime) { 2203 let YTPEvent = jQuery.Event('YTPTime'); 2204 YTPEvent.time = YTPlayer.currentTime; 2205 jQuery(YTPlayer).trigger(YTPEvent) 2206 } 2207 2208 YTPlayer.currentTime = prog.currentTime; 2209 YTPlayer.totalTime = YTPlayer.player.getDuration(); 2210 if (YTPlayer.player.getVolume() == 0) $YTPlayer.addClass('isMuted'); 2211 else $YTPlayer.removeClass('isMuted'); 2212 2213 if (YTPlayer.opt.showControls) 2214 if (prog.totalTime) { 2215 YTPlayer.controlBar.find('.mb_YTPTime').html(jQuery.mbYTPlayer.formatTime(prog.currentTime) + ' / ' + jQuery.mbYTPlayer.formatTime(prog.totalTime)) 2216 } else { 2217 YTPlayer.controlBar.find('.mb_YTPTime').html('-- : -- / -- : --') 2218 } 2219 2220 /** 2221 * Manage video pause on window blur 2222 */ 2223 if (eval(YTPlayer.opt.stopMovieOnBlur)) { 2224 if (!document.hasFocus()) { 2225 if (YTPlayer.state == 1) { 2226 YTPlayer.hasFocus = false; 2227 YTPlayer.preventTrigger = true; 2228 $YTPlayer.YTPPause() 2229 } 2230 } else if (document.hasFocus() && !YTPlayer.hasFocus && !(YTPlayer.state == -1 || YTPlayer.state == 0)) { 2231 YTPlayer.hasFocus = true; 2232 YTPlayer.preventTrigger = true; 2233 $YTPlayer.YTPPlay() 2234 } 2235 } 2236 2237 /** 2238 * Manage video pause if not on screen 2239 */ 2240 if (YTPlayer.opt.playOnlyIfVisible) { 2241 let isOnScreen = jQuery.mbYTPlayer.isOnScreen(YTPlayer, YTPlayer.opt.onScreenPercentage); 2242 if (!isOnScreen && YTPlayer.state == 1) { 2243 YTPlayer.isOnScreen = false; 2244 $YTPlayer.YTPPause() 2245 } else if (isOnScreen && !YTPlayer.isOnScreen) { 2246 YTPlayer.isOnScreen = true; 2247 YTPlayer.player.playVideo() 2248 } 2249 } 2250 2251 if (YTPlayer.controlBar.length && YTPlayer.controlBar.outerWidth() <= 400 && !YTPlayer.isCompact) { 2252 YTPlayer.controlBar.addClass('compact'); 2253 YTPlayer.isCompact = true; 2254 if (!YTPlayer.isMute && YTPlayer.volumeBar) YTPlayer.volumeBar.updateSliderVal(YTPlayer.opt.vol) 2255 } else if (YTPlayer.controlBar.length && YTPlayer.controlBar.outerWidth() > 400 && YTPlayer.isCompact) { 2256 YTPlayer.controlBar.removeClass('compact'); 2257 YTPlayer.isCompact = false; 2258 2259 if (!YTPlayer.isMute && YTPlayer.volumeBar) 2260 YTPlayer.volumeBar.updateSliderVal(YTPlayer.opt.vol) 2261 } 2262 // the video is ended 2263 if (YTPlayer.player.getPlayerState() > 0 && ((parseFloat(YTPlayer.player.getDuration() - (YTPlayer.opt.fadeOnStartTime / 1000)) < YTPlayer.player.getCurrentTime()) || (stopAt > 0 && parseFloat(YTPlayer.player.getCurrentTime()) >= stopAt))) { 2264 2265 if (YTPlayer.isEnded) 2266 return; 2267 2268 YTPlayer.isEnded = true; 2269 2270 setTimeout(function () { 2271 YTPlayer.isEnded = false 2272 }, 1000); 2273 2274 if (YTPlayer.isList) { 2275 if (!YTPlayer.opt.loop || (YTPlayer.opt.loop > 0 && YTPlayer.player.loopTime === YTPlayer.opt.loop - 1)) { 2276 YTPlayer.player.loopTime = undefined; 2277 clearInterval(YTPlayer.getState); 2278 let YTPEnd = jQuery.Event('YTPEnd'); 2279 YTPEnd.time = YTPlayer.currentTime; 2280 jQuery(YTPlayer).trigger(YTPEnd); 2281 return 2282 } 2283 } else if (!YTPlayer.opt.loop || (YTPlayer.opt.loop > 0 && YTPlayer.player.loopTime === YTPlayer.opt.loop - 1)) { 2284 YTPlayer.player.loopTime = undefined; 2285 2286 YTPlayer.state = 2; 2287 2288 $YTPlayer.changeCoverImage(YTPlayer); 2289 2290 jQuery(YTPlayer).YTPPause(); 2291 YTPlayer.wrapper.CSSAnimate({ 2292 opacity: 0 2293 }, YTPlayer.opt.fadeOnStartTime, function () { 2294 2295 if (YTPlayer.controlBar.length) 2296 YTPlayer.controlBar.find('.mb_YTPPlayPause').html(jQuery.mbYTPlayer.controls.play); 2297 2298 $YTPlayer.changeCoverImage(); 2299 2300 let YTPEnd = jQuery.Event('YTPEnd'); 2301 YTPEnd.time = YTPlayer.currentTime; 2302 jQuery(YTPlayer).trigger(YTPEnd); 2303 YTPlayer.player.seekTo(YTPlayer.opt.startAt, true); 2304 }); 2305 return 2306 } 2307 2308 YTPlayer.player.loopTime = YTPlayer.player.loopTime ? ++YTPlayer.player.loopTime : 1; 2309 YTPlayer.opt.startAt = YTPlayer.opt.startAt || 1; 2310 YTPlayer.preventTrigger = true; 2311 YTPlayer.state = 2; 2312 YTPlayer.player.seekTo(YTPlayer.opt.startAt, true) 2313 } 2314 }, interval) 2315 }, 2316 2317 /** 2318 * checkForStart 2319 * @param YTPlayer 2320 */ 2321 checkForStart: function (YTPlayer) { 2322 let $YTPlayer = jQuery(YTPlayer); 2323 2324 /* If the player has been removed from scene destroy it */ 2325 if (!jQuery.contains(document, YTPlayer)) { 2326 $YTPlayer.YTPPlayerDestroy(); 2327 return 2328 } 2329 2330 /* CREATE CONTROL BAR */ 2331 jQuery.mbYTPlayer.buildControls(YTPlayer); 2332 2333 if (YTPlayer.overlay) 2334 if (YTPlayer.opt.addRaster) { 2335 let classN = YTPlayer.opt.addRaster == 'dot' ? 'raster-dot' : 'raster'; 2336 YTPlayer.overlay.addClass(YTPlayer.isRetina ? classN + ' retina' : classN) 2337 } else { 2338 YTPlayer.overlay.removeClass(function (index, classNames) { 2339 // change the list into an array 2340 let current_classes = classNames.split(' '), 2341 // array of classes which are to be removed 2342 classes_to_remove = []; 2343 jQuery.each(current_classes, function (index, class_name) { 2344 // if the classname begins with bg add it to the classes_to_remove array 2345 if (/raster.*/.test(class_name)) { 2346 classes_to_remove.push(class_name) 2347 } 2348 }); 2349 classes_to_remove.push('retina'); 2350 // turn the array back into a string 2351 return classes_to_remove.join(' ') 2352 }) 2353 } 2354 2355 YTPlayer.preventTrigger = true; 2356 YTPlayer.state = 2; 2357 YTPlayer.preventTrigger = true; 2358 2359 YTPlayer.player.mute(); 2360 YTPlayer.player.playVideo(); 2361 YTPlayer.isStarting = true; 2362 2363 let startAt = YTPlayer.start_from_last ? YTPlayer.start_from_last : YTPlayer.opt.startAt ? YTPlayer.opt.startAt : 1; 2364 2365 YTPlayer.preventTrigger = true; 2366 YTPlayer.checkForStartAt = setInterval(function () { 2367 2368 YTPlayer.player.mute(); 2369 YTPlayer.player.seekTo(startAt, true); 2370 2371 let canPlayVideo = YTPlayer.player.getVideoLoadedFraction() >= startAt / YTPlayer.player.getDuration(); 2372 2373 if (jQuery.mbBrowser.mobile) 2374 canPlayVideo = true; 2375 2376 if (YTPlayer.player.getDuration() > 0 && YTPlayer.player.getCurrentTime() >= startAt && canPlayVideo) { 2377 YTPlayer.start_from_last = null; 2378 2379 YTPlayer.preventTrigger = true; 2380 $YTPlayer.YTPPause(); 2381 2382 clearInterval(YTPlayer.checkForStartAt); 2383 2384 if (typeof YTPlayer.opt.onReady == 'function') 2385 YTPlayer.opt.onReady(YTPlayer); 2386 2387 YTPlayer.isReady = true; 2388 2389 $YTPlayer.YTPRemoveFilter(); 2390 2391 if (YTPlayer.opt.addFilters) { 2392 $YTPlayer.YTPApplyFilters(YTPlayer.opt.addFilters) 2393 } else { 2394 $YTPlayer.YTPApplyFilters() 2395 } 2396 $YTPlayer.YTPEnableFilters(); 2397 let YTPready = jQuery.Event('YTPReady'); 2398 YTPready.time = YTPlayer.currentTime; 2399 $YTPlayer.trigger(YTPready); 2400 2401 YTPlayer.state = 2; 2402 2403 if (!YTPlayer.opt.mute) { 2404 2405 if (YTPlayer.opt.autoPlay) { 2406 console.debug('We muted the audio to make the video \'auto-play\' according with the latest vendor policy. ' + 2407 'The audio will unmute at the first user interaction with the page'); 2408 YTPlayer.player.mute(); 2409 YTPlayer.forcedMuted = true; 2410 /** 2411 * If autoPlay is set to true and mute is set to false 2412 * Browsers will not auto-play 2413 * Start playing audio after the first click 2414 */ 2415 jQuery(document).on('mousedown.YTPstartAudio', function () { 2416 if (YTPlayer.forcedMuted) { 2417 console.debug("AAAAAAA"); 2418 YTPlayer.player.unMute(); 2419 YTPlayer.forcedMuted = false; 2420 jQuery(document).off('mousedown.YTPstartAudio') 2421 } 2422 }); 2423 2424 jQuery(window).on("scroll", function () { 2425 console.debug("AAAAA") 2426 }) 2427 2428 } else { 2429 YTPlayer.player.unMute() 2430 } 2431 2432 } else { 2433 $YTPlayer.YTPMute() 2434 } 2435 2436 if (typeof _gaq != 'undefined' && eval(YTPlayer.opt.gaTrack)) 2437 _gaq.push(['_trackEvent', 'YTPlayer', 'Play', (YTPlayer.hasData ? YTPlayer.videoData.title : YTPlayer.videoID.toString())]); 2438 else if (typeof ga != 'undefined' && eval(YTPlayer.opt.gaTrack)) 2439 ga('send', 'event', 'YTPlayer', 'play', (YTPlayer.hasData ? YTPlayer.videoData.title : YTPlayer.videoID.toString())); 2440 2441 if (YTPlayer.opt.autoPlay) { 2442 2443 let YTPStart = jQuery.Event('YTPStart'); 2444 YTPStart.time = YTPlayer.currentTime; 2445 jQuery(YTPlayer).trigger(YTPStart); 2446 2447 YTPlayer.isStarting = false; 2448 2449 /* Fix for Safari freeze */ 2450 if (jQuery.mbBrowser.os.name === 'mac' && jQuery.mbBrowser.safari) { 2451 jQuery('body').one('mousedown.YTPstart', function () { 2452 $YTPlayer.YTPPlay() 2453 }) 2454 } 2455 $YTPlayer.YTPPlay(); 2456 console.timeEnd(YTPTimerLabels.startPlaying) 2457 } else { 2458 YTPlayer.preventTrigger = true; 2459 $YTPlayer.YTPPause(); 2460 2461 if (YTPlayer.start_from_last) 2462 YTPlayer.player.seekTo(startAt, true); 2463 2464 setTimeout(function () { 2465 YTPlayer.preventTrigger = true; 2466 $YTPlayer.YTPPause(); 2467 2468 if (!YTPlayer.isPlayer) { 2469 if (!YTPlayer.opt.coverImage) { 2470 jQuery(YTPlayer.playerEl).CSSAnimate({ 2471 opacity: 1 2472 }, YTPlayer.opt.fadeOnStartTime); 2473 YTPlayer.wrapper.CSSAnimate({ 2474 opacity: YTPlayer.isAlone ? 1 : YTPlayer.opt.opacity 2475 }, YTPlayer.opt.fadeOnStartTime) 2476 } else { 2477 YTPlayer.wrapper.css({opacity: 0}); 2478 setTimeout(function () { 2479 $YTPlayer.changeCoverImage() 2480 }, YTPlayer.opt.fadeOnStartTime) 2481 } 2482 } 2483 YTPlayer.isStarting = false 2484 }, 500); 2485 2486 if (YTPlayer.controlBar.length) 2487 YTPlayer.controlBar.find('.mb_YTPPlayPause').html(jQuery.mbYTPlayer.controls.play) 2488 } 2489 2490 if (YTPlayer.isPlayer && !YTPlayer.opt.autoPlay && (YTPlayer.loading && YTPlayer.loading.length)) { 2491 YTPlayer.loading.html('Ready'); 2492 setTimeout(function () { 2493 YTPlayer.loading.fadeOut() 2494 }, 100) 2495 } 2496 2497 if (YTPlayer.controlBar && YTPlayer.controlBar.length) 2498 YTPlayer.controlBar.slideDown(1000) 2499 } 2500 2501 if (jQuery.mbBrowser.os.name === 'mac' && jQuery.mbBrowser.safari) { 2502 YTPlayer.player.playVideo(); 2503 if (startAt >= 0) 2504 YTPlayer.player.seekTo(startAt, true) 2505 } 2506 2507 }, 100); 2508 2509 return $YTPlayer 2510 }, 2511 2512 /* TIME METHODS -------------------------------------------------------------------------------------------*/ 2513 2514 /** 2515 * getTime 2516 * @returns {string} time 2517 */ 2518 getTime: function () { 2519 let YTPlayer = this.get(0); 2520 return jQuery.mbYTPlayer.formatTime(YTPlayer.currentTime) 2521 }, 2522 2523 /** 2524 * getTotalTime 2525 * @returns {string} total time 2526 */ 2527 getTotalTime: function () { 2528 let YTPlayer = this.get(0); 2529 return jQuery.mbYTPlayer.formatTime(YTPlayer.totalTime) 2530 }, 2531 2532 /** 2533 * formatTime 2534 * @param s 2535 * @returns {string} 2536 */ 2537 formatTime: function (s) { 2538 let min = Math.floor(s / 60); 2539 let sec = Math.floor(s - (60 * min)); 2540 return (min <= 9 ? '0' + min : min) + ' : ' + (sec <= 9 ? '0' + sec : sec) 2541 }, 2542 2543 /* PLAYER POSITION AND SIZE OPTIMIZATION-------------------------------------------------------------------------------------------*/ 2544 2545 /** 2546 * setAnchor 2547 * @param anchor 2548 */ 2549 setAnchor: function (anchor) { 2550 let $YTplayer = this; 2551 $YTplayer.optimizeDisplay(anchor) 2552 }, 2553 2554 /** 2555 * getAnchor 2556 */ 2557 getAnchor: function () { 2558 let YTPlayer = this.get(0); 2559 return YTPlayer.opt.anchor 2560 }, 2561 2562 /** 2563 * setAbundance 2564 * @param val 2565 * @param updateOptions 2566 * @returns {jQuery.mbYTPlayer} 2567 */ 2568 setAbundance: function (val, updateOptions) { 2569 let YTPlayer = this.get(0); 2570 let $YTPlayer = this; 2571 if (updateOptions) 2572 YTPlayer.opt.abundance = val; 2573 $YTPlayer.optimizeDisplay(YTPlayer.opt.anchor, val); 2574 return $YTPlayer 2575 }, 2576 2577 /** 2578 * getAbundance 2579 * @returns {*} 2580 */ 2581 getAbundance: function () { 2582 let YTPlayer = this.get(0); 2583 return YTPlayer.opt.abundance 2584 }, 2585 2586 /** 2587 * setOption 2588 * @param opt 2589 * @param val 2590 * @returns {jQuery.mbYTPlayer} 2591 */ 2592 setOption: function (opt, val) { 2593 let YTPlayer = this.get(0); 2594 let $YTPlayer = this; 2595 YTPlayer.opt[opt] = val; 2596 return $YTPlayer 2597 } 2598 }; 2599 2600 /** 2601 * optimizeDisplay 2602 * @param anchor 2603 * @param abundanceX 2604 */ 2605 jQuery.fn.optimizeDisplay = function (anchor, abundanceX) { 2606 2607 let YTPlayer = this.get(0); 2608 let vid = {}; 2609 let el = YTPlayer.wrapper; 2610 let iframe = jQuery(YTPlayer.playerEl); 2611 2612 YTPlayer.opt.anchor = anchor || YTPlayer.opt.anchor; 2613 2614 // console.debug(YTPlayer.opt.anchor); 2615 2616 YTPlayer.opt.anchor = typeof YTPlayer.opt.anchor != 'undefined ' ? YTPlayer.opt.anchor : 'center,center'; 2617 let YTPAlign = YTPlayer.opt.anchor.split(','); 2618 let ab = abundanceX ? abundanceX : YTPlayer.opt.abundance; 2619 2620 if (YTPlayer.opt.optimizeDisplay) { 2621 let abundance = el.height() * ab; 2622 let win = {}; 2623 win.width = el.outerWidth(); 2624 win.height = el.outerHeight() + abundance; 2625 2626 YTPlayer.opt.ratio = YTPlayer.opt.ratio === 'auto' ? 16 / 9 : YTPlayer.opt.ratio; 2627 YTPlayer.opt.ratio = eval(YTPlayer.opt.ratio); 2628 2629 vid.width = win.width + abundance; 2630 vid.height = Math.ceil(vid.width / YTPlayer.opt.ratio); 2631 vid.marginTop = Math.ceil(-((vid.height - win.height + abundance) / 2)); 2632 vid.marginLeft = -(abundance / 2); 2633 let lowest = vid.height < win.height; 2634 2635 if (lowest) { 2636 vid.height = win.height + abundance; 2637 vid.width = Math.ceil(vid.height * YTPlayer.opt.ratio); 2638 vid.marginTop = -(abundance / 2); 2639 vid.marginLeft = Math.ceil(-((vid.width - win.width) / 2)) 2640 } 2641 2642 for (let a in YTPAlign) { 2643 if (YTPAlign.hasOwnProperty(a)) { 2644 let al = YTPAlign[a].replace(/ /g, ''); 2645 2646 switch (al) { 2647 case 'top': 2648 vid.marginTop = -abundance; 2649 break; 2650 case 'bottom': 2651 vid.marginTop = Math.ceil(-(vid.height - win.height) - (abundance / 2)); 2652 break; 2653 case 'left': 2654 vid.marginLeft = -(abundance); 2655 break; 2656 case 'right': 2657 vid.marginLeft = Math.ceil(-(vid.width - win.width) + (abundance / 2)); 2658 break 2659 } 2660 2661 } 2662 } 2663 2664 } else { 2665 vid.width = '100%'; 2666 vid.height = '100%'; 2667 vid.marginTop = 0; 2668 vid.marginLeft = 0 2669 } 2670 2671 iframe.css({ 2672 width : vid.width, 2673 height : vid.height, 2674 marginTop : vid.marginTop, 2675 marginLeft: vid.marginLeft, 2676 maxWidth : 'initial' 2677 }) 2678 2679 2680 }; 2681 2682 2683 /* UTILITIES -----------------------------------------------------------------------------------------------------------------------*/ 2684 2685 /** 2686 * shuffle 2687 * @param arr 2688 * @returns {Array|string|Blob|*} 2689 * 2690 */ 2691 jQuery.shuffle = function (arr) { 2692 let newArray = arr.slice(); 2693 let len = newArray.length; 2694 let i = len; 2695 while (i--) { 2696 let p = parseInt(Math.random() * len); 2697 let t = newArray[i]; 2698 newArray[i] = newArray[p]; 2699 newArray[p] = t 2700 } 2701 return newArray; 2702 }; 2703 2704 /** 2705 * Unselectable 2706 * @returns {*} 2707 */ 2708 jQuery.fn.unselectable = function () { 2709 return this.each(function () { 2710 jQuery(this).css({ 2711 '-moz-user-select' : 'none', 2712 '-webkit-user-select': 'none', 2713 'user-select' : 'none' 2714 }).attr('unselectable', 'on') 2715 }) 2716 }; 2717 2718 /* EXTERNAL METHODS -----------------------------------------------------------------------------------------------------------------------*/ 2719 2720 jQuery.fn.YTPlayer = jQuery.mbYTPlayer.buildPlayer; 2721 jQuery.fn.mb_YTPlayer = jQuery.mbYTPlayer.buildPlayer; 2722 2723 jQuery.fn.YTPCheckForState = jQuery.mbYTPlayer.checkForState; 2724 2725 jQuery.fn.YTPGetPlayer = jQuery.mbYTPlayer.getPlayer; 2726 jQuery.fn.YTPGetVideoID = jQuery.mbYTPlayer.getVideoID; 2727 jQuery.fn.YTPGetPlaylistID = jQuery.mbYTPlayer.getPlaylistID; 2728 jQuery.fn.YTPChangeVideo = jQuery.fn.YTPChangeMovie = jQuery.mbYTPlayer.changeVideo; 2729 jQuery.fn.YTPPlayerDestroy = jQuery.mbYTPlayer.playerDestroy; 2730 2731 jQuery.fn.YTPPlay = jQuery.mbYTPlayer.play; 2732 jQuery.fn.YTPTogglePlay = jQuery.mbYTPlayer.togglePlay; 2733 jQuery.fn.YTPStop = jQuery.mbYTPlayer.stop; 2734 jQuery.fn.YTPPause = jQuery.mbYTPlayer.pause; 2735 jQuery.fn.YTPSeekTo = jQuery.mbYTPlayer.seekTo; 2736 2737 jQuery.fn.YTPGetPlaybackRate = jQuery.mbYTPlayer.getPlaybackRate; 2738 jQuery.fn.YTPSetPlaybackRate = jQuery.mbYTPlayer.setPlaybackRate; 2739 2740 jQuery.fn.changeCoverImage = jQuery.mbYTPlayer.changeCoverImage; 2741 2742 jQuery.fn.YTPlaylist = jQuery.mbYTPlayer.playlist; 2743 jQuery.fn.YTPPlayNext = jQuery.mbYTPlayer.playNext; 2744 jQuery.fn.YTPPlayPrev = jQuery.mbYTPlayer.playPrev; 2745 jQuery.fn.YTPPlayIndex = jQuery.mbYTPlayer.playIndex; 2746 2747 jQuery.fn.YTPMute = jQuery.mbYTPlayer.mute; 2748 jQuery.fn.YTPUnmute = jQuery.mbYTPlayer.unmute; 2749 jQuery.fn.YTPToggleVolume = jQuery.mbYTPlayer.toggleVolume; 2750 jQuery.fn.YTPSetVolume = jQuery.mbYTPlayer.setVolume; 2751 jQuery.fn.YTPGetVolume = jQuery.mbYTPlayer.getVolume; 2752 2753 jQuery.fn.YTPGetVideoData = jQuery.mbYTPlayer.getVideoData; 2754 jQuery.fn.YTPFullscreen = jQuery.mbYTPlayer.fullscreen; 2755 jQuery.fn.YTPToggleLoops = jQuery.mbYTPlayer.toggleLoops; 2756 jQuery.fn.YTPManageProgress = jQuery.mbYTPlayer.manageProgress; 2757 2758 jQuery.fn.YTPSetVideoQuality = jQuery.mbYTPlayer.setVideoQuality; 2759 jQuery.fn.YTPGetVideoQuality = jQuery.mbYTPlayer.getVideoQuality; 2760 2761 jQuery.fn.YTPApplyFilter = jQuery.mbYTPlayer.applyFilter; 2762 jQuery.fn.YTPApplyFilters = jQuery.mbYTPlayer.applyFilters; 2763 jQuery.fn.YTPToggleFilter = jQuery.mbYTPlayer.toggleFilter; 2764 jQuery.fn.YTPToggleFilters = jQuery.mbYTPlayer.toggleFilters; 2765 jQuery.fn.YTPRemoveFilter = jQuery.mbYTPlayer.removeFilter; 2766 jQuery.fn.YTPDisableFilters = jQuery.mbYTPlayer.disableFilters; 2767 jQuery.fn.YTPEnableFilters = jQuery.mbYTPlayer.enableFilters; 2768 jQuery.fn.YTPGetFilters = jQuery.mbYTPlayer.getFilters; 2769 2770 jQuery.fn.YTPGetTime = jQuery.mbYTPlayer.getTime; 2771 jQuery.fn.YTPGetTotalTime = jQuery.mbYTPlayer.getTotalTime; 2772 2773 jQuery.fn.YTPAddMask = jQuery.mbYTPlayer.addMask; 2774 jQuery.fn.YTPRemoveMask = jQuery.mbYTPlayer.removeMask; 2775 jQuery.fn.YTPToggleMask = jQuery.mbYTPlayer.toggleMask; 2776 2777 jQuery.fn.YTPGetAbundance = jQuery.mbYTPlayer.getAbundance; 2778 jQuery.fn.YTPSetAbundance = jQuery.mbYTPlayer.setAbundance; 2779 2780 jQuery.fn.YTPSetAnchor = jQuery.mbYTPlayer.setAnchor; 2781 jQuery.fn.YTPGetAnchor = jQuery.mbYTPlayer.getAnchor; 2782 2783 jQuery.fn.YTPSetOption = jQuery.mbYTPlayer.setOption 2784 2785})(jQuery, ytp);
vendor: 8,868 bytes, lines 2786-2818
2786/*___________________________________________________________________________________________________________________________________________________ 2787 _ jquery.mb.components _ 2788 _ _ 2789 _ file: jquery.mb.mbBrowser.min.js _ 2790 _ last modified: 24/05/17 19.56 _ 2791 _ _ 2792 _ Open Lab s.r.l., Florence - Italy _ 2793 _ _ 2794 _ email: [email protected] _ 2795 _ site: http://pupunzi.com _ 2796 _ http://open-lab.com _ 2797 _ blog: http://pupunzi.open-lab.com _ 2798 _ Q&A: http://jquery.pupunzi.com _ 2799 _ _ 2800 _ Licences: MIT, GPL _ 2801 _ http://www.opensource.org/licenses/mit-license.php _ 2802 _ http://www.gnu.org/licenses/gpl.html _ 2803 _ _ 2804 _ Copyright (c) 2001-2017. Matteo Bicocchi (Pupunzi); _ 2805 ___________________________________________________________________________________________________________________________________________________*/ 2806var nAgt=navigator.userAgent;jQuery.mbBrowser=jQuery.mbBrowser||{};jQuery.mbBrowser.mozilla=!1;jQuery.mbBrowser.webkit=!1;jQuery.mbBrowser.opera=!1;jQuery.mbBrowser.safari=!1;jQuery.mbBrowser.chrome=!1;jQuery.mbBrowser.androidStock=!1;jQuery.mbBrowser.msie=!1;jQuery.mbBrowser.edge=!1;jQuery.mbBrowser.ua=nAgt;function isTouchSupported(){var a=nAgt.msMaxTouchPoints,e="ontouchstart"in document.createElement("div");return a||e?!0:!1} 2807var getOS=function(){var a={version:"Unknown version",name:"Unknown OS"};-1!=navigator.appVersion.indexOf("Win")&&(a.name="Windows");-1!=navigator.appVersion.indexOf("Mac")&&0>navigator.appVersion.indexOf("Mobile")&&(a.name="Mac");-1!=navigator.appVersion.indexOf("Linux")&&(a.name="Linux");/Mac OS X/.test(nAgt)&&!/Mobile/.test(nAgt)&&(a.version=/Mac OS X ([\._\d]+)/.exec(nAgt)[1],a.version=a.version.replace(/_/g,".").substring(0,5));/Windows/.test(nAgt)&&(a.version="Unknown.Unknown");/Windows NT 5.1/.test(nAgt)&& 2808(a.version="5.1");/Windows NT 6.0/.test(nAgt)&&(a.version="6.0");/Windows NT 6.1/.test(nAgt)&&(a.version="6.1");/Windows NT 6.2/.test(nAgt)&&(a.version="6.2");/Windows NT 10.0/.test(nAgt)&&(a.version="10.0");/Linux/.test(nAgt)&&/Linux/.test(nAgt)&&(a.version="Unknown.Unknown");a.name=a.name.toLowerCase();a.major_version="Unknown";a.minor_version="Unknown";"Unknown.Unknown"!=a.version&&(a.major_version=parseFloat(a.version.split(".")[0]),a.minor_version=parseFloat(a.version.split(".")[1]));return a}; 2809jQuery.mbBrowser.os=getOS();jQuery.mbBrowser.hasTouch=isTouchSupported();jQuery.mbBrowser.name=navigator.appName;jQuery.mbBrowser.fullVersion=""+parseFloat(navigator.appVersion);jQuery.mbBrowser.majorVersion=parseInt(navigator.appVersion,10);var nameOffset,verOffset,ix; 2810if(-1!=(verOffset=nAgt.indexOf("Opera")))jQuery.mbBrowser.opera=!0,jQuery.mbBrowser.name="Opera",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+6),-1!=(verOffset=nAgt.indexOf("Version"))&&(jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+8));else if(-1!=(verOffset=nAgt.indexOf("OPR")))jQuery.mbBrowser.opera=!0,jQuery.mbBrowser.name="Opera",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+4);else if(-1!=(verOffset=nAgt.indexOf("MSIE")))jQuery.mbBrowser.msie=!0,jQuery.mbBrowser.name="Microsoft Internet Explorer", 2811 jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+5);else if(-1!=nAgt.indexOf("Trident")){jQuery.mbBrowser.msie=!0;jQuery.mbBrowser.name="Microsoft Internet Explorer";var start=nAgt.indexOf("rv:")+3,end=start+4;jQuery.mbBrowser.fullVersion=nAgt.substring(start,end)}else-1!=(verOffset=nAgt.indexOf("Edge"))?(jQuery.mbBrowser.edge=!0,jQuery.mbBrowser.name="Microsoft Edge",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+5)):-1!=(verOffset=nAgt.indexOf("Chrome"))?(jQuery.mbBrowser.webkit=!0,jQuery.mbBrowser.chrome= 2812 !0,jQuery.mbBrowser.name="Chrome",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+7)):-1<nAgt.indexOf("mozilla/5.0")&&-1<nAgt.indexOf("android ")&&-1<nAgt.indexOf("applewebkit")&&!(-1<nAgt.indexOf("chrome"))?(verOffset=nAgt.indexOf("Chrome"),jQuery.mbBrowser.webkit=!0,jQuery.mbBrowser.androidStock=!0,jQuery.mbBrowser.name="androidStock",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+7)):-1!=(verOffset=nAgt.indexOf("Safari"))?(jQuery.mbBrowser.webkit=!0,jQuery.mbBrowser.safari=!0,jQuery.mbBrowser.name= 2813 "Safari",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+7),-1!=(verOffset=nAgt.indexOf("Version"))&&(jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+8))):-1!=(verOffset=nAgt.indexOf("AppleWebkit"))?(jQuery.mbBrowser.webkit=!0,jQuery.mbBrowser.safari=!0,jQuery.mbBrowser.name="Safari",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+7),-1!=(verOffset=nAgt.indexOf("Version"))&&(jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+8))):-1!=(verOffset=nAgt.indexOf("Firefox"))?(jQuery.mbBrowser.mozilla= 2814 !0,jQuery.mbBrowser.name="Firefox",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+8)):(nameOffset=nAgt.lastIndexOf(" ")+1)<(verOffset=nAgt.lastIndexOf("/"))&&(jQuery.mbBrowser.name=nAgt.substring(nameOffset,verOffset),jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+1),jQuery.mbBrowser.name.toLowerCase()==jQuery.mbBrowser.name.toUpperCase()&&(jQuery.mbBrowser.name=navigator.appName)); 2815-1!=(ix=jQuery.mbBrowser.fullVersion.indexOf(";"))&&(jQuery.mbBrowser.fullVersion=jQuery.mbBrowser.fullVersion.substring(0,ix));-1!=(ix=jQuery.mbBrowser.fullVersion.indexOf(" "))&&(jQuery.mbBrowser.fullVersion=jQuery.mbBrowser.fullVersion.substring(0,ix));jQuery.mbBrowser.majorVersion=parseInt(""+jQuery.mbBrowser.fullVersion,10);isNaN(jQuery.mbBrowser.majorVersion)&&(jQuery.mbBrowser.fullVersion=""+parseFloat(navigator.appVersion),jQuery.mbBrowser.majorVersion=parseInt(navigator.appVersion,10)); 2816jQuery.mbBrowser.version=jQuery.mbBrowser.majorVersion;jQuery.mbBrowser.android=/Android/i.test(nAgt);jQuery.mbBrowser.blackberry=/BlackBerry|BB|PlayBook/i.test(nAgt);jQuery.mbBrowser.ios=/iPhone|iPad|iPod|webOS/i.test(nAgt);jQuery.mbBrowser.operaMobile=/Opera Mini/i.test(nAgt);jQuery.mbBrowser.windowsMobile=/IEMobile|Windows Phone/i.test(nAgt);jQuery.mbBrowser.kindle=/Kindle|Silk/i.test(nAgt); 2817jQuery.mbBrowser.mobile=jQuery.mbBrowser.android||jQuery.mbBrowser.blackberry||jQuery.mbBrowser.ios||jQuery.mbBrowser.windowsMobile||jQuery.mbBrowser.operaMobile||jQuery.mbBrowser.kindle;jQuery.isMobile=jQuery.mbBrowser.mobile;jQuery.isTablet=jQuery.mbBrowser.mobile&&765<jQuery(window).width();jQuery.isAndroidDefault=jQuery.mbBrowser.android&&!/chrome/i.test(nAgt);jQuery.mbBrowser=jQuery.mbBrowser; 2818jQuery.mbBrowser.versionCompare=function(a,e){if("stringstring"!=typeof a+typeof e)return!1;for(var c=a.split("."),d=e.split("."),b=0,f=Math.max(c.length,d.length);b<f;b++){if(c[b]&&!d[b]&&0<parseInt(c[b])||parseInt(c[b])>parseInt(d[b]))return 1;if(d[b]&&!c[b]&&0<parseInt(d[b])||parseInt(c[b])<parseInt(d[b]))return-1}return 0};
vendor: 24,124 bytes, lines 2819-2932
2819/* 2820 * ****************************************************************************** 2821 * jquery.mb.components 2822 * file: jquery.mb.CSSAnimate.min.js 2823 * 2824 * Copyright (c) 2001-2014. Matteo Bicocchi (Pupunzi); 2825 * Open lab srl, Firenze - Italy 2826 * email: [email protected] 2827 * site: http://pupunzi.com 2828 * blog: http://pupunzi.open-lab.com 2829 * http://open-lab.com 2830 * 2831 * Licences: MIT, GPL 2832 * http://www.opensource.org/licenses/mit-license.php 2833 * http://www.gnu.org/licenses/gpl.html 2834 * 2835 * last modified: 26/03/14 21.40 2836 * ***************************************************************************** 2837 */ 2838 2839jQuery.support.CSStransition=function(){var d=(document.body||document.documentElement).style;return void 0!==d.transition||void 0!==d.WebkitTransition||void 0!==d.MozTransition||void 0!==d.MsTransition||void 0!==d.OTransition}();function uncamel(d){return d.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()})}function setUnit(d,a){return"string"!==typeof d||d.match(/^[\-0-9\.]+jQuery/)?""+d+a:d} 2840function setFilter(d,a,b){var c=uncamel(a),g=jQuery.mbBrowser.mozilla?"":jQuery.CSS.sfx;d[g+"filter"]=d[g+"filter"]||"";b=setUnit(b>jQuery.CSS.filters[a].max?jQuery.CSS.filters[a].max:b,jQuery.CSS.filters[a].unit);d[g+"filter"]+=c+"("+b+") ";delete d[a]} 2841jQuery.CSS={name:"mb.CSSAnimate",author:"Matteo Bicocchi",version:"2.0.0",transitionEnd:"transitionEnd",sfx:"",filters:{blur:{min:0,max:100,unit:"px"},brightness:{min:0,max:400,unit:"%"},contrast:{min:0,max:400,unit:"%"},grayscale:{min:0,max:100,unit:"%"},hueRotate:{min:0,max:360,unit:"deg"},invert:{min:0,max:100,unit:"%"},saturate:{min:0,max:400,unit:"%"},sepia:{min:0,max:100,unit:"%"}},normalizeCss:function(d){var a=jQuery.extend(!0,{},d);jQuery.mbBrowser.webkit||jQuery.mbBrowser.opera?jQuery.CSS.sfx= 2842 "-webkit-":jQuery.mbBrowser.mozilla?jQuery.CSS.sfx="-moz-":jQuery.mbBrowser.msie&&(jQuery.CSS.sfx="-ms-");jQuery.CSS.sfx="";for(var b in a){"transform"===b&&(a[jQuery.CSS.sfx+"transform"]=a[b],delete a[b]);"transform-origin"===b&&(a[jQuery.CSS.sfx+"transform-origin"]=d[b],delete a[b]);"filter"!==b||jQuery.mbBrowser.mozilla||(a[jQuery.CSS.sfx+"filter"]=d[b],delete a[b]);"blur"===b&&setFilter(a,"blur",d[b]);"brightness"===b&&setFilter(a,"brightness",d[b]);"contrast"===b&&setFilter(a,"contrast",d[b]);"grayscale"=== 2843b&&setFilter(a,"grayscale",d[b]);"hueRotate"===b&&setFilter(a,"hueRotate",d[b]);"invert"===b&&setFilter(a,"invert",d[b]);"saturate"===b&&setFilter(a,"saturate",d[b]);"sepia"===b&&setFilter(a,"sepia",d[b]);if("x"===b){var c=jQuery.CSS.sfx+"transform";a[c]=a[c]||"";a[c]+=" translateX("+setUnit(d[b],"px")+")";delete a[b]}"y"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" translateY("+setUnit(d[b],"px")+")",delete a[b]);"z"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" translateZ("+ 2844 setUnit(d[b],"px")+")",delete a[b]);"rotate"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" rotate("+setUnit(d[b],"deg")+")",delete a[b]);"rotateX"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" rotateX("+setUnit(d[b],"deg")+")",delete a[b]);"rotateY"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" rotateY("+setUnit(d[b],"deg")+")",delete a[b]);"rotateZ"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" rotateZ("+setUnit(d[b],"deg")+")",delete a[b]);"scale"===b&& 2845(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" scale("+setUnit(d[b],"")+")",delete a[b]);"scaleX"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" scaleX("+setUnit(d[b],"")+")",delete a[b]);"scaleY"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" scaleY("+setUnit(d[b],"")+")",delete a[b]);"scaleZ"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" scaleZ("+setUnit(d[b],"")+")",delete a[b]);"skew"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" skew("+setUnit(d[b], 2846 "deg")+")",delete a[b]);"skewX"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" skewX("+setUnit(d[b],"deg")+")",delete a[b]);"skewY"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" skewY("+setUnit(d[b],"deg")+")",delete a[b]);"perspective"===b&&(c=jQuery.CSS.sfx+"transform",a[c]=a[c]||"",a[c]+=" perspective("+setUnit(d[b],"px")+")",delete a[b])}return a},getProp:function(d){var a=[],b;for(b in d)0>a.indexOf(b)&&a.push(uncamel(b));return a.join(",")},animate:function(d,a,b,c,g){return this.each(function(){function n(){e.called= 2847 !0;e.CSSAIsRunning=!1;h.off(jQuery.CSS.transitionEnd+"."+e.id);clearTimeout(e.timeout);h.css(jQuery.CSS.sfx+"transition","");"function"==typeof g&&g.apply(e);"function"==typeof e.CSSqueue&&(e.CSSqueue(),e.CSSqueue=null)}var e=this,h=jQuery(this);e.id=e.id||"CSSA_"+(new Date).getTime();var k=k||{type:"noEvent"};if(e.CSSAIsRunning&&e.eventType==k.type&&!jQuery.mbBrowser.msie&&9>=jQuery.mbBrowser.version)e.CSSqueue=function(){h.CSSAnimate(d,a,b,c,g)};else if(e.CSSqueue=null,e.eventType=k.type,0!==h.length&& 2848 d){d=jQuery.normalizeCss(d);e.CSSAIsRunning=!0;"function"==typeof a&&(g=a,a=jQuery.fx.speeds._default);"function"==typeof b&&(c=b,b=0);"string"==typeof b&&(g=b,b=0);"function"==typeof c&&(g=c,c="cubic-bezier(0.65,0.03,0.36,0.72)");if("string"==typeof a)for(var l in jQuery.fx.speeds)if(a==l){a=jQuery.fx.speeds[l];break}else a=jQuery.fx.speeds._default;a||(a=jQuery.fx.speeds._default);"string"===typeof g&&(c=g,g=null);if(jQuery.support.CSStransition){var f={"default":"ease","in":"ease-in",out:"ease-out", 2849 "in-out":"ease-in-out",snap:"cubic-bezier(0,1,.5,1)",easeOutCubic:"cubic-bezier(.215,.61,.355,1)",easeInOutCubic:"cubic-bezier(.645,.045,.355,1)",easeInCirc:"cubic-bezier(.6,.04,.98,.335)",easeOutCirc:"cubic-bezier(.075,.82,.165,1)",easeInOutCirc:"cubic-bezier(.785,.135,.15,.86)",easeInExpo:"cubic-bezier(.95,.05,.795,.035)",easeOutExpo:"cubic-bezier(.19,1,.22,1)",easeInOutExpo:"cubic-bezier(1,0,0,1)",easeInQuad:"cubic-bezier(.55,.085,.68,.53)",easeOutQuad:"cubic-bezier(.25,.46,.45,.94)",easeInOutQuad:"cubic-bezier(.455,.03,.515,.955)", 2850 easeInQuart:"cubic-bezier(.895,.03,.685,.22)",easeOutQuart:"cubic-bezier(.165,.84,.44,1)",easeInOutQuart:"cubic-bezier(.77,0,.175,1)",easeInQuint:"cubic-bezier(.755,.05,.855,.06)",easeOutQuint:"cubic-bezier(.23,1,.32,1)",easeInOutQuint:"cubic-bezier(.86,0,.07,1)",easeInSine:"cubic-bezier(.47,0,.745,.715)",easeOutSine:"cubic-bezier(.39,.575,.565,1)",easeInOutSine:"cubic-bezier(.445,.05,.55,.95)",easeInBack:"cubic-bezier(.6,-.28,.735,.045)",easeOutBack:"cubic-bezier(.175, .885,.32,1.275)",easeInOutBack:"cubic-bezier(.68,-.55,.265,1.55)"}; 2851 f[c]&&(c=f[c]);h.off(jQuery.CSS.transitionEnd+"."+e.id);f=jQuery.CSS.getProp(d);var m={};jQuery.extend(m,d);m[jQuery.CSS.sfx+"transition-property"]=f;m[jQuery.CSS.sfx+"transition-duration"]=a+"ms";m[jQuery.CSS.sfx+"transition-delay"]=b+"ms";m[jQuery.CSS.sfx+"transition-timing-function"]=c;setTimeout(function(){h.one(jQuery.CSS.transitionEnd+"."+e.id,n);h.css(m)},1);e.timeout=setTimeout(function(){e.called||!g?(e.called=!1,e.CSSAIsRunning=!1):(h.css(jQuery.CSS.sfx+"transition",""),g.apply(e),e.CSSAIsRunning= 2852 !1,"function"==typeof e.CSSqueue&&(e.CSSqueue(),e.CSSqueue=null))},a+b+10)}else{for(f in d)"transform"===f&&delete d[f],"filter"===f&&delete d[f],"transform-origin"===f&&delete d[f],"auto"===d[f]&&delete d[f],"x"===f&&(k=d[f],l="left",d[l]=k,delete d[f]),"y"===f&&(k=d[f],l="top",d[l]=k,delete d[f]),"-ms-transform"!==f&&"-ms-filter"!==f||delete d[f];h.delay(b).animate(d,a,g)}}})}};jQuery.fn.CSSAnimate=jQuery.CSS.animate;jQuery.normalizeCss=jQuery.CSS.normalizeCss; 2853jQuery.fn.css3=function(d){return this.each(function(){var a=jQuery(this),b=jQuery.normalizeCss(d);a.css(b)})}; 2854/*___________________________________________________________________________________________________________________________________________________ 2855 _ jquery.mb.components _ 2856 _ _ 2857 _ file: jquery.mb.simpleSlider.min.js _ 2858 _ last modified: 09/05/17 19.31 _ 2859 _ _ 2860 _ Open Lab s.r.l., Florence - Italy _ 2861 _ _ 2862 _ email: [email protected] _ 2863 _ site: http://pupunzi.com _ 2864 _ http://open-lab.com _ 2865 _ blog: http://pupunzi.open-lab.com _ 2866 _ Q&A: http://jquery.pupunzi.com _ 2867 _ _ 2868 _ Licences: MIT, GPL _ 2869 _ http://www.opensource.org/licenses/mit-license.php _ 2870 _ http://www.gnu.org/licenses/gpl.html _ 2871 _ _ 2872 _ Copyright (c) 2001-2017. Matteo Bicocchi (Pupunzi); _ 2873 ___________________________________________________________________________________________________________________________________________________*/ 2874(function(b){b.simpleSlider={defaults:{initialval:0,maxval:100,orientation:"h",readonly:!1,callback:!1},events:{start:b.mbBrowser.mobile?"touchstart":"mousedown",end:b.mbBrowser.mobile?"touchend":"mouseup",move:b.mbBrowser.mobile?"touchmove":"mousemove"},init:function(d){return this.each(function(){var a=this,c=b(a);c.addClass("simpleSlider");a.opt={};b.extend(a.opt,b.simpleSlider.defaults,d);b.extend(a.opt,c.data());var f="h"===a.opt.orientation?"horizontal":"vertical";f=b("<div/>").addClass("level").addClass(f); 2875 c.prepend(f);a.level=f;c.css({cursor:"default"});"auto"==a.opt.maxval&&(a.opt.maxval=b(a).outerWidth());c.updateSliderVal();a.opt.readonly||(c.on(b.simpleSlider.events.start,function(e){b.mbBrowser.mobile&&(e=e.changedTouches[0]);a.canSlide=!0;c.updateSliderVal(e);"h"===a.opt.orientation?c.css({cursor:"col-resize"}):c.css({cursor:"row-resize"});a.lastVal=a.val;b.mbBrowser.mobile||(e.preventDefault(),e.stopPropagation())}),b(document).on(b.simpleSlider.events.move,function(e){b.mbBrowser.mobile&&(e=e.changedTouches[0]); 2876 a.canSlide&&(b(document).css({cursor:"default"}),c.updateSliderVal(e),b.mbBrowser.mobile||(e.preventDefault(),e.stopPropagation()))}).on(b.simpleSlider.events.end,function(){b(document).css({cursor:"auto"});a.canSlide=!1;c.css({cursor:"auto"})}))})},updateSliderVal:function(d){var a=this.get(0);if(a.opt){a.opt.initialval="number"==typeof a.opt.initialval?a.opt.initialval:a.opt.initialval(a);var c=b(a).outerWidth(),f=b(a).outerHeight();a.x="object"==typeof d?d.clientX+document.body.scrollLeft-this.offset().left: 2877 "number"==typeof d?d*c/a.opt.maxval:a.opt.initialval*c/a.opt.maxval;a.y="object"==typeof d?d.clientY+document.body.scrollTop-this.offset().top:"number"==typeof d?(a.opt.maxval-a.opt.initialval-d)*f/a.opt.maxval:a.opt.initialval*f/a.opt.maxval;a.y=this.outerHeight()-a.y;a.scaleX=a.x*a.opt.maxval/c;a.scaleY=a.y*a.opt.maxval/f;a.outOfRangeX=a.scaleX>a.opt.maxval?a.scaleX-a.opt.maxval:0>a.scaleX?a.scaleX:0;a.outOfRangeY=a.scaleY>a.opt.maxval?a.scaleY-a.opt.maxval:0>a.scaleY?a.scaleY:0;a.outOfRange="h"=== 2878 a.opt.orientation?a.outOfRangeX:a.outOfRangeY;a.value="undefined"!=typeof d?"h"===a.opt.orientation?a.x>=this.outerWidth()?a.opt.maxval:0>=a.x?0:a.scaleX:a.y>=this.outerHeight()?a.opt.maxval:0>=a.y?0:a.scaleY:"h"===a.opt.orientation?a.scaleX:a.scaleY;"h"===a.opt.orientation?a.level.width(Math.floor(100*a.x/c)+"%"):a.level.height(Math.floor(100*a.y/f));a.lastVal===a.value&&("h"===a.opt.orientation&&(a.x>=this.outerWidth()||0>=a.x)||"h"!==a.opt.orientation&&(a.y>=this.outerHeight()||0>=a.y))||("function"=== 2879 typeof a.opt.callback&&a.opt.callback(a),a.lastVal=a.value)}}};b.fn.simpleSlider=b.simpleSlider.init;b.fn.updateSliderVal=b.simpleSlider.updateSliderVal})(jQuery); 2880/*___________________________________________________________________________________________________________________________________________________ 2881 _ jquery.mb.components _ 2882 _ _ 2883 _ file: jquery.mb.storage.min.js _ 2884 _ last modified: 24/05/15 16.08 _ 2885 _ _ 2886 _ Open Lab s.r.l., Florence - Italy _ 2887 _ _ 2888 _ email: [email protected] _ 2889 _ site: http://pupunzi.com _ 2890 _ http://open-lab.com _ 2891 _ blog: http://pupunzi.open-lab.com _ 2892 _ Q&A: http://jquery.pupunzi.com _ 2893 _ _ 2894 _ Licences: MIT, GPL _ 2895 _ http://www.opensource.org/licenses/mit-license.php _ 2896 _ http://www.gnu.org/licenses/gpl.html _ 2897 _ _ 2898 _ Copyright (c) 2001-2015. Matteo Bicocchi (Pupunzi); _ 2899 ___________________________________________________________________________________________________________________________________________________*/ 2900 2901(function(d){d.mbCookie={set:function(a,c,f,b){"object"==typeof c&&(c=JSON.stringify(c));b=b?"; domain="+b:"";var e=new Date,d="";0<f&&(e.setTime(e.getTime()+864E5*f),d="; expires="+e.toGMTString());document.cookie=a+"="+c+d+"; path=/"+b},get:function(a){a+="=";for(var c=document.cookie.split(";"),d=0;d<c.length;d++){for(var b=c[d];" "==b.charAt(0);)b=b.substring(1,b.length);if(0==b.indexOf(a))try{return JSON.parse(b.substring(a.length,b.length))}catch(e){return b.substring(a.length,b.length)}}return null}, 2902 remove:function(a){d.mbCookie.set(a,"",-1)}};d.mbStorage={set:function(a,c){"object"==typeof c&&(c=JSON.stringify(c));localStorage.setItem(a,c)},get:function(a){if(localStorage[a])try{return JSON.parse(localStorage[a])}catch(c){return localStorage[a]}else return null},remove:function(a){a?localStorage.removeItem(a):localStorage.clear()}}})(jQuery); 2903/*___________________________________________________________________________________________________________________________________________________ 2904 _ jquery.mb.components _ 2905 _ _ 2906 _ file: jquery.mbBrowser.min.js _ 2907 _ last modified: 1/23/21 4:18 PM _ 2908 _ _ 2909 _ Open Lab s.r.l., Florence - Italy _ 2910 _ _ 2911 _ email: [email protected] _ 2912 _ site: http://pupunzi.com _ 2913 _ http://open-lab.com _ 2914 _ blog: http://pupunzi.open-lab.com _ 2915 _ Q&A: http://jquery.pupunzi.com _ 2916 _ _ 2917 _ Licences: MIT, GPL _ 2918 _ http://www.opensource.org/licenses/mit-license.php _ 2919 _ http://www.gnu.org/licenses/gpl.html _ 2920 _ _ 2921 _ Copyright (c) 2001-2021. Matteo Bicocchi (Pupunzi); _ 2922 ___________________________________________________________________________________________________________________________________________________*/ 2923 2924var nAgt=navigator.userAgent;jQuery.mbBrowser={};jQuery.mbBrowser.mozilla=!1;jQuery.mbBrowser.webkit=!1;jQuery.mbBrowser.opera=!1;jQuery.mbBrowser.safari=!1;jQuery.mbBrowser.chrome=!1;jQuery.mbBrowser.androidStock=!1;jQuery.mbBrowser.msie=!1;jQuery.mbBrowser.edge=!1;jQuery.mbBrowser.ua=nAgt;function isTouchSupported(){var a=nAgt.msMaxTouchPoints,e="ontouchstart"in document.createElement("div");return a||e?!0:!1} 2925var getOS=function(){var a={version:"Unknown version",name:"Unknown OS"};-1!=navigator.appVersion.indexOf("Win")&&(a.name="Windows");-1!=navigator.appVersion.indexOf("Mac")&&0>navigator.appVersion.indexOf("Mobile")&&(a.name="Mac");-1!=navigator.appVersion.indexOf("Linux")&&(a.name="Linux");/Mac OS X/.test(nAgt)&&!/Mobile/.test(nAgt)&&(a.version=/Mac OS X ([\._\d]+)/.exec(nAgt)[1],a.version=a.version.replace(/_/g,".").substring(0,5));/Windows/.test(nAgt)&&(a.version="Unknown.Unknown");/Windows NT 5.1/.test(nAgt)&& 2926(a.version="5.1");/Windows NT 6.0/.test(nAgt)&&(a.version="6.0");/Windows NT 6.1/.test(nAgt)&&(a.version="6.1");/Windows NT 6.2/.test(nAgt)&&(a.version="6.2");/Windows NT 10.0/.test(nAgt)&&(a.version="10.0");/Linux/.test(nAgt)&&/Linux/.test(nAgt)&&(a.version="Unknown.Unknown");a.name=a.name.toLowerCase();a.major_version="Unknown";a.minor_version="Unknown";"Unknown.Unknown"!=a.version&&(a.major_version=parseFloat(a.version.split(".")[0]),a.minor_version=parseFloat(a.version.split(".")[1]));return a}; 2927jQuery.mbBrowser.os=getOS();jQuery.mbBrowser.hasTouch=isTouchSupported();jQuery.mbBrowser.name=navigator.appName;jQuery.mbBrowser.fullVersion=""+parseFloat(navigator.appVersion);jQuery.mbBrowser.majorVersion=parseInt(navigator.appVersion,10);var nameOffset,verOffset,ix; 2928if(-1!=(verOffset=nAgt.indexOf("Opera")))jQuery.mbBrowser.opera=!0,jQuery.mbBrowser.name="Opera",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+6),-1!=(verOffset=nAgt.indexOf("Version"))&&(jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+8));else if(-1!=(verOffset=nAgt.indexOf("OPR")))jQuery.mbBrowser.opera=!0,jQuery.mbBrowser.name="Opera",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+4);else if(-1!=(verOffset=nAgt.indexOf("MSIE")))jQuery.mbBrowser.msie=!0,jQuery.mbBrowser.name= 2929 "Microsoft Internet Explorer",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+5);else if(-1!=nAgt.indexOf("Trident")){jQuery.mbBrowser.msie=!0;jQuery.mbBrowser.name="Microsoft Internet Explorer";var start=nAgt.indexOf("rv:")+3,end=start+4;jQuery.mbBrowser.fullVersion=nAgt.substring(start,end)}else-1!=(verOffset=nAgt.indexOf("Edge"))?(jQuery.mbBrowser.edge=!0,jQuery.mbBrowser.name="Microsoft Edge",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+5)):-1!=(verOffset=nAgt.indexOf("Chrome"))? 2930 (jQuery.mbBrowser.webkit=!0,jQuery.mbBrowser.chrome=!0,jQuery.mbBrowser.name="Chrome",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+7)):-1<nAgt.indexOf("mozilla/5.0")&&-1<nAgt.indexOf("android ")&&-1<nAgt.indexOf("applewebkit")&&!(-1<nAgt.indexOf("chrome"))?(verOffset=nAgt.indexOf("Chrome"),jQuery.mbBrowser.webkit=!0,jQuery.mbBrowser.androidStock=!0,jQuery.mbBrowser.name="androidStock",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+7)):-1!=(verOffset=nAgt.indexOf("Safari"))?(jQuery.mbBrowser.webkit= 2931 !0,jQuery.mbBrowser.safari=!0,jQuery.mbBrowser.name="Safari",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+7),-1!=(verOffset=nAgt.indexOf("Version"))&&(jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+8))):-1!=(verOffset=nAgt.indexOf("AppleWebkit"))?(jQuery.mbBrowser.webkit=!0,jQuery.mbBrowser.safari=!0,jQuery.mbBrowser.name="Safari",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+7),-1!=(verOffset=nAgt.indexOf("Version"))&&(jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+ 2932 8))):-1!=(verOffset=nAgt.indexOf("Firefox"))?(jQuery.mbBrowser.mozilla=!0,jQuery.mbBrowser.name="Firefox",jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+8)):(nameOff
2932set=nAgt.lastIndexOf(" ")+1)<(verOffset=nAgt.lastIndexOf("/"))&&(jQuery.mbBrowser.name=nAgt.substring(nameOffset,verOffset),jQuery.mbBrowser.fullVersion=nAgt.substring(verOffset+1),jQuery.mbBrowser.name.toLowerCase()==jQuery.mbBrowser.name.toUpperCase()&&(jQuery.mbBrowser.name=navigator.appName)); 2933-1!=(ix=jQuery.mbBrowser.fullVersion.indexOf(";"))&&(jQuery.mbBrowser.fullVersion=jQuery.mbBrowser.fullVersion.substring(0,ix));-1!=(ix=jQuery.mbBrowser.fullVersion.indexOf(" "))&&(jQuery.mbBrowser.fullVersion=jQuery.mbBrowser.fullVersion.substring(0,ix));jQuery.mbBrowser.majorVersion=parseInt(""+jQuery.mbBrowser.fullVersion,10);isNaN(jQuery.mbBrowser.majorVersion)&&(jQuery.mbBrowser.fullVersion=""+parseFloat(navigator.appVersion),jQuery.mbBrowser.majorVersion=parseInt(navigator.appVersion,10)); 2934jQuery.mbBrowser.version=jQuery.mbBrowser.majorVersion;jQuery.mbBrowser.android=/Android/i.test(nAgt);jQuery.mbBrowser.blackberry=/BlackBerry|BB|PlayBook/i.test(nAgt);jQuery.mbBrowser.ios=/iPhone|iPad|iPod|webOS/i.test(nAgt);jQuery.mbBrowser.operaMobile=/Opera Mini/i.test(nAgt);jQuery.mbBrowser.windowsMobile=/IEMobile|Windows Phone/i.test(nAgt);jQuery.mbBrowser.kindle=/Kindle|Silk/i.test(nAgt); 2935jQuery.mbBrowser.mobile=jQuery.mbBrowser.android||jQuery.mbBrowser.blackberry||jQuery.mbBrowser.ios||jQuery.mbBrowser.windowsMobile||jQuery.mbBrowser.operaMobile||jQuery.mbBrowser.kindle;jQuery.isMobile=jQuery.mbBrowser.mobile;jQuery.isTablet=jQuery.mbBrowser.mobile&&765<jQuery(window).width();jQuery.isAndroidDefault=jQuery.mbBrowser.android&&!/chrome/i.test(nAgt);jQuery.mbBrowser=jQuery.mbBrowser; 2936jQuery.mbBrowser.versionCompare=function(a,e){if("stringstring"!=typeof a+typeof e)return!1;for(var c=a.split("."),d=e.split("."),b=0,f=Math.max(c.length,d.length);b<f;b++){if(c[b]&&!d[b]&&0<parseInt(c[b])||parseInt(c[b])>parseInt(d[b]))return 1;if(d[b]&&!c[b]&&0<parseInt(d[b])||parseInt(c[b])<parseInt(d[b]))return-1}return 0}; 2937; 2938/** 2939 * Makes "skip to content" link work correctly in IE9, Chrome, and Opera 2940 * for better accessibility. 2941 * 2942 * @link http://www.nczonline.net/blog/2013/01/15/fixing-skip-to-content-links/ 2943 */ 2944 2945( function() { 2946 var ua = navigator.userAgent.toLowerCase(); 2947 2948 if ( ( ua.indexOf( 'webkit' ) > -1 || ua.indexOf( 'opera' ) > -1 || ua.indexOf( 'msie' ) > -1 ) && 2949 document.getElementById && window.addEventListener ) { 2950 2951 window.addEventListener( 'hashchange', function() { 2952 var element = document.getElementById( location.hash.substring( 1 ) ); 2953 2954 if ( element ) { 2955 if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.nodeName ) ) { 2956 element.tabIndex = -1; 2957 } 2958 2959 element.focus(); 2960 } 2961 }, false ); 2962 } 2963} )(); 2964; 2965/* global screenReaderText */ 2966/** 2967 * Theme functions file. 2968 * 2969 * Contains handlers for navigation and widget area. 2970 */ 2971 2972( function( $ ) { 2973 var $body, $window, $sidebar, resizeTimer, 2974 secondary, button; 2975 2976 function initMainNavigation( container ) { 2977 // Add dropdown toggle that display child menu items. 2978 container.find( '.menu-item-has-children > a' ).after( '<button class="dropdown-toggle" aria-expanded="false">' + screenReaderText.expand + '</button>' ); 2979 2980 // Toggle buttons and submenu items with active children menu items. 2981 container.find( '.current-menu-ancestor > button' ).addClass( 'toggle-on' ); 2982 container.find( '.current-menu-ancestor > .sub-menu' ).addClass( 'toggled-on' ); 2983 2984 container.find( '.dropdown-toggle' ).on( 'click', function( e ) { 2985 var _this = $( this ); 2986 e.preventDefault(); 2987 _this.toggleClass( 'toggle-on' ); 2988 _this.next( '.children, .sub-menu' ).toggleClass( 'toggled-on' ); 2989 _this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' ); 2990 _this.html( _this.html() === screenReaderText.expand ? screenReaderText.collapse : screenReaderText.expand ); 2991 } ); 2992 } 2993 initMainNavigation( $( '.main-navigation' ) ); 2994 2995 // Re-initialize the main navigation when it is updated, persisting any existing submenu expanded states. 2996 $( document ).on( 'customize-preview-menu-refreshed', function( e, params ) { 2997 if ( 'primary' === params.wpNavMenuArgs.theme_location ) { 2998 initMainNavigation( params.newContainer ); 2999 3000 // Re-sync expanded states from oldContainer. 3001 params.oldContainer.find( '.dropdown-toggle.toggle-on' ).each(function() { 3002 var containerId = $( this ).parent().prop( 'id' ); 3003 $( params.newContainer ).find( '#' + containerId + ' > .dropdown-toggle' ).triggerHandler( 'click' ); 3004 }); 3005 } 3006 }); 3007 3008 secondary = $( '#secondary' ); 3009 button = $( '.site-branding' ).find( '.secondary-toggle' ); 3010 3011 // Enable menu toggle for small screens. 3012 ( function() { 3013 var menu, widgets, social; 3014 if ( ! secondary.length || ! button.length ) { 3015 return; 3016 } 3017 3018 // Hide button if there are no widgets and the menus are missing or empty. 3019 menu = secondary.find( '.nav-menu' ); 3020 widgets = secondary.find( '#widget-area' ); 3021 social = secondary.find( '#social-navigation' ); 3022 if ( ! widgets.length && ! social.length && ( ! menu.length || ! menu.children().length ) ) { 3023 button.hide(); 3024 return; 3025 } 3026 3027 button.on( 'click.twentyfifteen', function() { 3028 secondary.toggleClass( 'toggled-on' ); 3029 secondary.trigger( 'resize' ); 3030 $( this ).toggleClass( 'toggled-on' ); 3031 if ( $( this, secondary ).hasClass( 'toggled-on' ) ) { 3032 $( this ).attr( 'aria-expanded', 'true' ); 3033 secondary.attr( 'aria-expanded', 'true' ); 3034 } else { 3035 $( this ).attr( 'aria-expanded', 'false' ); 3036 secondary.attr( 'aria-expanded', 'false' ); 3037 } 3038 } ); 3039 } )(); 3040 3041 /** 3042 * Add or remove ARIA attributes. 3043 * 3044 * Uses jQuery's width() function to determine the size of the window and add 3045 * the default ARIA attributes for the menu toggle if it's visible. 3046 * 3047 * @since Twenty Fifteen 1.1 3048 */ 3049 function onResizeARIA() { 3050 if ( 955 > $window.width() ) { 3051 button.attr( 'aria-expanded', 'false' ); 3052 secondary.attr( 'aria-expanded', 'false' ); 3053 button.attr( 'aria-controls', 'secondary' ); 3054 } else { 3055 button.removeAttr( 'aria-expanded' ); 3056 secondary.removeAttr( 'aria-expanded' ); 3057 button.removeAttr( 'aria-controls' ); 3058 } 3059 } 3060 3061 // Sidebar scrolling. 3062 function resizeAndScroll() { 3063 var windowPos = $window.scrollTop(), 3064 windowHeight = $window.height(), 3065 sidebarHeight = $sidebar.height(), 3066 bodyHeight = $body.height(); 3067 3068 if( 955 < $window.width() && bodyHeight > sidebarHeight && ( windowPos + windowHeight ) >= sidebarHeight ) { 3069 $sidebar.css({ 3070 position: 'fixed', 3071 bottom: sidebarHeight > windowHeight ? 0 : 'auto' 3072 }); 3073 } else { 3074 $sidebar.css('position', 'relative'); 3075 } 3076 } 3077 3078 $( document ).ready( function() { 3079 $body = $( document.body ); 3080 $window = $( window ); 3081 $sidebar = $( '#sidebar' ).first(); 3082 3083 $window 3084 .on( 'scroll.twentyfifteen', resizeAndScroll ) 3085 .on( 'load.twentyfifteen', onResizeARIA ) 3086 .on( 'resize.twentyfifteen', function() { 3087 clearTimeout( resizeTimer ); 3088 resizeTimer = setTimeout( resizeAndScroll, 500 ); 3089 onResizeARIA(); 3090 } ); 3091 $sidebar.on( 'click.twentyfifteen keydown.twentyfifteen', 'button', resizeAndScroll ); 3092 3093 for ( var i = 0; i < 6; i++ ) { 3094 setTimeout( resizeAndScroll, 100 * i ); 3095 } 3096 } ); 3097 3098} )( jQuery ); 3099; 3100// For compatibility with optimizers 3101if (document.readyState !== 'loading') { 3102 //console.log('Newsletter loaded (late)'); 3103 tnp_ajax_init(); 3104} else { 3105 document.addEventListener("DOMContentLoaded", function () { 3106 //console.log('Newsletter loaded'); 3107 tnp_ajax_init(); 3108 }); 3109} 3110 3111function tnp_ajax_init() { 3112 document.querySelectorAll('form.tnp-ajax').forEach(el => { 3113 el.addEventListener('submit', async function(ev) { 3114 ev.preventDefault(); 3115 ev.stopPropagation(); 3116 const response = await fetch(newsletter_data.action_url + '?action=tnp&na=sa', { 3117 method: "POST", 3118 body: new FormData(this) 3119 }); 3120 this.innerHTML = await response.text(); 3121 }); 3122 }); 3123} 3124 3125 3126 3127;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.