· 8 years ago · Jan 13, 2018, 10:28 PM
1/*
2 * MHP1138 Player v.3.2.0
3 */
4
5MHP1138.skinsMarkup['html'] = "<template class=mhp1138_gridTemplate><div class=mhp1138_gridContainer><div class=mhp1138_gridWrapper><div class=mhp1138_thumbnailsGrid></div></div></div></template><template class=mhp1138_gridItemTemplate><a href='<%= url %>' title='<%= title %>' draggable=false class=mhp1138_gridItem style='background-image:url('<%= thumbnail %>')'><div class=mhp1138_info><div class=mhp1138_title><%= title %></div><div class=mhp1138_stats><div class=mhp1138_time><%= time %></div><div class=mhp1138_rating><i class='mhp1138_mhp1138_grid-icon mhp1138_mhp1138_grid-icon-thumb-up'></i><%= percentage %>%</div></div></div></a></template><template class=mhp1138_logo_tube8><svg class=mhp1138_tube8 viewBox='1968 3562 2355 860'><path d='m4251 3994c0 202-164 367-367 367-202 0-367-164-367-367 0-202 164-367 367-367 202 0 367 164 367 367z' fill=#ccc /><circle cy=3994 cx=3884 r=349 fill=#fff /><path d='m4211 3994c0 180-146 327-327 327-180 0-327-146-327-327 0-180 146-327 327-327 180 0 327 146 327 327z' fill=#231F20 /><g opacity=.35><radialGradient id=a1_ gradientUnits=userSpaceOnUse cy=4736 cx=9218.8 gradientTransform='matrix(.4116 0 0 -.4116 0 588)' r=1019.6><stop stop-color=#fff offset=0 /><stop offset=.8681 /></radialGradient><path d='m4211 3994c0 180-146 327-327 327-180 0-327-146-327-327 0-180 146-327 327-327 180 0 327 146 327 327z' fill=url(#a1_) /></g><path d='m3810 4205c-114 0-206-91-206-203s92-203 206-203 206 91 206 203-92 203-206 203z' fill=#fff /><path d='m3810 3792c116 0 211 93 211 209s-94 209-211 209-211-93-211-209 95-209 211-209m0 11c-111 0-201 89-201 198s91 199 201 199 201-89 201-198-90-199-201-199z' fill=#231F20 /><path d='m1986 3816h345v91h-116v277h-114v-277h-116l1-91z' fill=#fff /><path d='m2331 3816v91h-116v277h-114v-277h-116v-91h346m0-19h-345c-10 0-19 8-19 19v91c0 10 8 19 19 19h98v258c0 10 8 19 18 19h114c10 0 19-8 19-19v-258h98c10 0 18-8 18-19v-91c-2-11-10-19-20-19z' fill=#231F20 /><path d='m2613 3816h113v219c0 22-3 42-10 61s-17 36-32 51c-14 14-30 25-45 30-22 8-49 12-79 12-18 0-37-1-58-4-21-2-39-7-53-15-14-7-27-18-39-32s-20-28-24-42c-7-23-11-44-11-62v-219h113v224c0 20 5 36 16 47s26 17 46 17 35-5 46-16 16-27 16-47l1-224z' fill=#fff /><path d='m2726 3816v219c0 22-3 42-10 61s-17 36-32 51c-14 14-30 25-45 30-22 8-49 12-79 12-18 0-37-1-58-4-21-2-39-7-53-15-14-7-27-18-39-32s-20-28-24-42c-7-23-11-44-11-62v-219h113v224c0 20 5 36 16 47s26 17 46 17 35-5 46-16 16-27 16-47v-224h114m0-19h-113c-10 0-19 8-19 19v224c0 16-4 27-11 34s-19 11-33 11c-15 0-26-4-33-12-8-8-12-19-12-34v-224c0-10-8-19-18-19h-113c-10 0-18 8-18 19v219c0 20 4 42 11 67 5 17 14 33 28 49 13 15 28 28 44 36 16 9 36 14 59 17 22 2 42 4 61 4 33 0 62-5 86-14 18-7 36-19 52-35s28-36 36-58c7-21 11-44 11-67v-219c0-9-8-17-18-17z' fill=#231F20 /><path d='m2792 3816h212c35 0 63 9 81 26 19 18 28 39 28 65 0 22-7 40-20 56-9 10-22 19-40 25 26 6 46 17 58 33s19 35 19 58c0 19-5 36-13 51-9 15-21 27-36 36-9 5-24 9-43 12-26 3-42 5-51 5h-196v-367h1zm115 144h49c18 0 30-3 37-9s10-15 10-26-3-19-10-25-19-9-36-9h-50v69zm0 144h58c19 0 33-3 41-10s12-16 12-28c0-11-4-20-12-26s-22-10-42-10h-58v74h1z' fill=#fff /><path d='m3005 3816c35 0 63 9 81 26 19 18 28 39 28 65 0 22-7 40-20 56-9 10-22 19-40 25 26 6 46 17 58 33s19 35 19 58c0 19-5 36-13 51-9 15-21 27-36 36-9 5-24 9-43 12-26 3-42 5-51 5h-196v-367h213m-98 144h49c18 0 30-3 37-9s10-15 10-26-3-19-10-25-19-9-36-9h-50v69m0 144h58c19 0 33-3 41-10s12-16 12-28c0-11-4-20-12-26s-22-10-42-10h-58v74m99-307h-212c-10 0-18 8-18 19v367c0 10 8 19 18 19h196c9 0 27-2 53-5 22-3 38-7 50-14 18-10 33-25 43-43s16-38 16-61c0-28-8-51-23-70-8-9-17-18-29-24 4-3 7-6 10-9 16-19 25-42 25-68 0-31-12-58-34-79-24-21-55-32-95-32zm-80 111h32c18 0 23 4 24 5 2 2 4 5 4 11 0 9-3 12-4 13s-6 5-25 5h-31v-34zm0 140h40c21 0 28 5 30 6 4 3 5 7 5 12 0 8-3 12-6 14-2 2-9 6-29 6h-40v-38z' fill=#231F20 /><path d='m3182 3816h304v79h-191v58h177v75h-177v72h196v83h-309v-367z' fill=#fff /><path d='m3486 3816v79h-191v58h177v75h-177v72h196v83h-309v-367h304m0-19h-304c-10 0-18 8-18 19v367c0 10 8 19 18 19h309c10 0 19-8 19-19v-83c0-10-8-19-19-19h-177v-36h158c10 0 19-8 19-18v-75c0-10-8-19-19-19h-158v-22h172c10 0 19-8 19-19v-79c0-8-8-16-19-16z' fill=#231F20 /><g fill=none><path d='m3788 4021h-3c-3 0-5 1-9 3-4 3-7 7-9 16 0 2-1 4-1 6 0 5 1 7 3 11 4 5 6 7 10 8h2c2 0 5-1 9-4 5-3 7-7 9-15 0-2 1-5 1-6 0-5-1-8-3-11-2-6-4-7-9-8z'/><path d='m3809 3917h-4c-2 0-4 0-6 2s-4 3-5 8v4c0 3 0 4 2 6s3 4 9 5h3c2 0 3 0 5-2s3-3 5-8v-4c0-3 0-4-2-6-1-2-2-4-7-5z'/></g><path d='m3734 3969c-10-8-17-17-21-26-5-12-7-24-4-37 4-22 18-38 42-48 18-7 41-9 67-4 35 7 60 19 74 35 14 17 19 35 15 56-2 12-8 22-16 31-7 7-16 12-28 18 13 9 22 21 26 33 5 13 6 26 3 40-2 13-8 25-16 35s-17 18-28 22c-10 5-22 7-35 7-14 0-28-1-43-4-28-5-49-13-62-22-14-9-23-21-28-35s-6-29-3-45c3-15 9-28 19-37 9-10 22-16 38-19zm17 67c-2 12 0 22 5 30 6 9 13 14 22 16s17 0 26-7c8-6 14-15 16-26 2-12 1-22-5-30-5-9-13-14-22-16s-18 0-26 6c-9 6-14 14-16 27zm26-113c-2 9 0 17 4 23 5 7 12 11 21 13 8 2 16 0 22-4s11-11 12-20c2-9 0-17-4-24-5-7-11-11-20-13s-16 0-23 4c-7 6-11 13-12 21z' fill=#231F20 /><path d='m4323 4203c-6-43-43-72-75-90-6-3-12-7-17-9-8-4-16-7-21-10-1 0-2-1-3-1-13 3-21 18-11 34 1 1 2 1 2 2 6 4 13 8 20 11 3 2 6 3 9 5 2 1 5 3 8 5 23 13 51 31 53 58 2 31-21 55-40 63-23 10-62 9-97 7-9-1-17-1-25-2-2 0-5 0-7-1-6-1-14-2-24-2-56-6-159-19-199-20-103-1-117 36-121 63-16-2-20-7-28-19 2 9 5 19 7 27 2 9 5 18 7 27 2 7 3 14 5 22 3 15 5 31 7 51 5-18 11-32 17-44 3-6 7-12 10-17 5-7 10-14 15-20 6-7 14-14 21-21-18 5-22 5-38 1 7-42 64-48 120-45 65 3 103 11 147 19 10 2 21 4 32 5 8 1 17 2 26 4 2 0 3 0 5 1 42 5 88 7 125-4 31-13 75-38 70-100z' fill=#981a20 /><path d='m4151 3562s13 57 4 79c0 0-3 27-67 52 0 0 25 54 72 65 0 0 38-46 32-100 0 0-3-42-41-96z' fill=#981a20 /><path d='m3614 3562s-13 57-3 79c0 0 3 27 67 52 0 0-24 55-72 66 0 0-38-46-33-100 0-1 4-43 41-97z' fill=#981a20 /></svg></template><template class=mhp1138_logo_youporn><svg class=mhp1138_youporn viewBox='0 0 300 44'><path class=mhp1138_st0 fill=#FFF d='M39.2.5l-15 21.8v21h-9v-21L0 .5h10.2l9.4 14L29 .4h10.2zM61 .5c13 0 22 9.8 22 21.5 0 12.7-10 21.5-22 21.5-13 0-21.8-9.7-21.8-21.5C39.2 9.8 48.8.5 61.2.5zm0 35c8 0 12.6-6.2 12.6-13.5 0-8-5.4-13.4-12.5-13.4-7.8 0-12.5 6-12.5 13.4 0 7.3 5 13.4 12.6 13.4zM127 .5v23.3c0 11-7.2 19.7-18.6 19.7-11 0-18.6-8.5-18.6-19.7V.5h9v23c0 5.7 3 11.7 9.6 11.7 6.4 0 9.6-5.6 9.6-11.8V.4h9z'/><path class=mhp1138_st1 fill=#EC6397 d='M153.7.5c6.3 0 11.7 5 11.7 11.6 0 6.4-5 11.7-11.7 11.7h-14.2v19.8H136V.5h17.7zm-.2 20c4.3 0 8.4-3.5 8.4-8.3C162 8 158 4 153.4 4h-14v16.4h14zM255 43.5l-11.4-19.8H231v19.8h-3.6V.5h17.8c6.3 0 11.7 5 11.7 11.6 0 5.6-3.8 10-9.4 11.4l11.7 20H255zm-24-23h14c4.2 0 8.3-3.5 8.3-8.3 0-4.3-3.7-8.2-8.4-8.2h-14v16.4zM300 .5v43h-2.5l-28-36.8v36.8H266V.5h2.4l28 36.8V.5h3.6zM196.4 43.5c-.4 0-.8 0-1-.4-9.3-7.3-24.8-22-24.8-30.2 0-3.3 1.3-6.4 3.6-8.7C176.5 2 179.6.6 183 .6c4 0 7.5 2 10 5l3.4 5 3.5-5c2.2-3 6-5 10-5 3.2 0 6.3 1.3 8.6 3.6 2.3 2.4 3.6 5.5 3.6 8.8 0 8-15.6 22.8-24.7 30.3-.4.4-.7.5-1 .5zM183 4c-2.5 0-4.7.8-6.4 2.5-1.7 1.7-2.6 4-2.6 6.3 0 5.4 11.3 17.6 22.4 26.7 11-9 22.4-21.3 22.4-26.7 0-2.4-1-4.6-2.6-6.3-1.7-1.7-4-2.6-6.3-2.6-3 0-5.6 1.2-7.3 3.6l-5 6.7c-.2.4-.7.7-1.3.7-.5 0-1-.3-1.4-.7l-5-6.7C188.5 5.3 186 4 183 4z'/></svg></template><template class=mhp1138_logo_redtube><svg class=mhp1138_redtube viewBox='0 0 2949 577'><g fill=#fff><path d='m1349 0h367v49h-157v514h-54v-514h-157v-49z'/><path d='m2127 380c0 129-62 197-187 197s-187-68-187-197v-380h54v379c0 110 49 149 134 149s134-40 134-149v-379h54v380z'/><path d='m2174 0h202c149 0 168 100 168 132 0 74-32 112-103 126v2c83 8 123 73 123 147 0 81-54 157-183 157h-208v-564zm53 237h133c82 0 130-33 130-95 0-70-41-93-125-93h-137v188zm0 277h155c92 0 128-54 128-108 0-71-52-120-147-120h-136v228z'/><path d='m2600 0h332v49h-278v199h98v49h-98v217h295v49h-349v-563z'/></g><path d='m501 0h366v98h-260v128h124v94h-124v146h281v98h-387v-564z' fill=#AE2024 /><path d='m939 0h156c195 0 277 120 277 282 0 184-89 282-257 282h-176v-564zm106 465h55c104 0 161-38 161-184 0-111-48-184-164-184h-52v368z' fill=#AE2024 /><path d='m339 336c27-10 112-40 112-166 0-99-70-170-190-170h-199l134 93h35c74 0 108 33 108 85 0 53-39 85-93 85h-52l-132 91v209h107v-207h64l109 207h123l-126-227z' fill=#AE2024 /><polygon points='0 41 195 178 0 314' fill=#AE2024 /><defs><filter id=Adobe_OpacityMaskFilter height=563 width=1372 y=0 x=0 filterUnits=userSpaceOnUse><feColorMatrix values='1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0' type=matrix /></filter></defs><mask id=a1_ height=563 width=1372 y=0 x=0 maskUnits=userSpaceOnUse><g filter=url(#Adobe_OpacityMaskFilter)><radialGradient id=a2_ gradientUnits=userSpaceOnUse cy=-37.753 cx=.7542 gradientTransform='matrix(.9447 -.869 1.3413 1.4581 85.667 44.719)' r=501.25><stop stop-color=#fff offset=0 /><stop stop-color=#EFEFEF offset=.043581 /><stop stop-color=#A8A8A8 offset=.2516 /><stop stop-color=#6C6C6C offset=.4476 /><stop stop-color=#3D3D3D offset=.6259 /><stop stop-color=#1C1C1C offset=.7831 /><stop stop-color=#070707 offset=.9131 /><stop offset=1 /></radialGradient><path d='m831-545c371 404 460 926 199 1166-262 241-775 108-1146-295-371-404-460-926-199-1167 262-240 775-108 1146 296z' fill=url(#a2_) /></g></mask><g fill=#C97175 mask=url(#a1_)><polygon points='501 0 868 0 868 98 607 98 607 226 732 226 732 320 607 320 607 465 888 465 888 563 501 563'/><path d='m1095 0h-156v563h176c168 0 257-98 257-282 0-161-82-281-277-281zm5 465h-55v-367h52c115 0 164 73 164 184 0 145-57 183-161 183z'/><path d='m339 336c27-10 112-40 112-166 0-99-70-170-190-170h-199l134 93h35c74 0 108 33 108 85 0 53-39 85-93 85h-52l-132 91v209h107v-207h64l109 207h123l-126-227z'/><polygon points='0 314 195 178 0 41'/></g></svg></template><template class=mhp1138_logo_pornhub><svg class=mhp1138_pornhub viewBox='725 3310 4666 1308'><path d='m5295 3310h-1898c-59 7-92 43-97 109v1091c5 66 38 102 96 109h1899c59-7 91-43 96-109v-1092c-5-65-38-101-96-108z' fill=#f90 /><path d='m3960 3812c-15-20-35-37-63-50-25-11-54-18-84-19h-2c-63-3-145 15-184 52v-257h-151v790h151v-287c0-48 5-85 14-109s24-43 44-55 42-18 67-18c22 0 41 5 55 15 15 9 24 22 31 38s8 54 8 114v302h151v-336c0-51-2-90-8-114-5-23-15-46-29-66z'/><path d='m4455 3998c0 82-4 133-11 155-8 21-21 39-42 53-21 15-44 21-70 21-23 0-41-5-56-16s-25-25-31-43c-5-18-8-67-8-148v-263h-151v363c0 54 7 96 21 127s36 54 67 71c31 17 65 25 103 25 6 0 11 0 17-1h1c96-3 147-47 172-76v63h141v-573h-151l-2 242z'/><path d='m5190 3819c-32-36-76-58-122-69-14-4-29-6-46-7-62-5-142 19-180 50l9-256h-151v790h140v-44c32 26 85 57 164 57h9 6c67 0 123-27 170-80s70-129 70-226c-1-92-24-164-69-215zm-123 361c-24 28-52 43-86 43-44 0-78-20-105-60-18-28-28-72-28-132 0-57 12-100 36-129 24-28 54-42 90-42 37 0 67 15 91 44s36 77 36 142c2 60-10 104-34 134z'/><g fill=#fff><path d='m1194 3495c-31-8-98-12-200-12h-269v832h168v-314h109c76 0 134-4 174-12 30-6 59-20 87-40s52-47 70-82c18-34 28-78 28-129 0-66-16-120-48-162-32-41-71-69-119-81zm-24 310c-13 18-30 32-53 41-22 8-67 13-133 13h-92v-236h81c60 0 101 2 121 5 28 5 50 17 67 37 18 20 27 44 27 75 1 25-5 46-18 65z'/><path d='m1706 3698c-59 0-112 13-160 39s-85 64-111 113c-26 50-39 101-39 154 0 69 13 128 39 176s64 85 114 109c50 25 103 37 158 37 90 0 163-30 222-90s88-135 88-226c0-90-29-165-87-224s-132-88-224-88zm106 452c-28 32-63 47-105 47-41 0-77-16-105-47-28-32-43-77-43-137s15-106 43-137c28-32 63-47 105-47s76 16 105 47c28 32 42 77 42 136 0 60-14 106-42 138z'/><path d='m2356 3700c-47 6-93 44-112 68v-57h-148v602h159v-186c0-103 5-170 13-202 9-32 21-54 37-67s34-18 57-18c23 0 48 8 75 26l50-139c-34-20-69-30-105-30-9 1-17 1-26 3z'/><path d='m3116 3832c-6-25-16-47-31-67s-37-36-66-48c-29-13-61-19-96-19-63-4-168 21-198 70v-57h-148v602h159v-273c0-67 4-113 12-138s23-45 45-60 47-23 74-23c21 0 40 5 55 16s27 25 33 44c7 19 10 61 10 126v308h159v-374c0-46-2-82-8-107z'/></g></svg></template><template class=mhp1138_logo_thumbzilla><svg class=mhp1138_thumbzilla viewBox='725 3310 4666 1308'><path d='m5295 3310h-1898c-59 7-92 43-97 109v1091c5 66 38 102 96 109h1899c59-7 91-43 96-109v-1092c-5-65-38-101-96-108z' fill=#f90 /><path d='m3960 3812c-15-20-35-37-63-50-25-11-54-18-84-19h-2c-63-3-145 15-184 52v-257h-151v790h151v-287c0-48 5-85 14-109s24-43 44-55 42-18 67-18c22 0 41 5 55 15 15 9 24 22 31 38s8 54 8 114v302h151v-336c0-51-2-90-8-114-5-23-15-46-29-66z'/><path d='m4455 3998c0 82-4 133-11 155-8 21-21 39-42 53-21 15-44 21-70 21-23 0-41-5-56-16s-25-25-31-43c-5-18-8-67-8-148v-263h-151v363c0 54 7 96 21 127s36 54 67 71c31 17 65 25 103 25 6 0 11 0 17-1h1c96-3 147-47 172-76v63h141v-573h-151l-2 242z'/><path d='m5190 3819c-32-36-76-58-122-69-14-4-29-6-46-7-62-5-142 19-180 50l9-256h-151v790h140v-44c32 26 85 57 164 57h9 6c67 0 123-27 170-80s70-129 70-226c-1-92-24-164-69-215zm-123 361c-24 28-52 43-86 43-44 0-78-20-105-60-18-28-28-72-28-132 0-57 12-100 36-129 24-28 54-42 90-42 37 0 67 15 91 44s36 77 36 142c2 60-10 104-34 134z'/><g fill=#fff><path d='m1194 3495c-31-8-98-12-200-12h-269v832h168v-314h109c76 0 134-4 174-12 30-6 59-20 87-40s52-47 70-82c18-34 28-78 28-129 0-66-16-120-48-162-32-41-71-69-119-81zm-24 310c-13 18-30 32-53 41-22 8-67 13-133 13h-92v-236h81c60 0 101 2 121 5 28 5 50 17 67 37 18 20 27 44 27 75 1 25-5 46-18 65z'/><path d='m1706 3698c-59 0-112 13-160 39s-85 64-111 113c-26 50-39 101-39 154 0 69 13 128 39 176s64 85 114 109c50 25 103 37 158 37 90 0 163-30 222-90s88-135 88-226c0-90-29-165-87-224s-132-88-224-88zm106 452c-28 32-63 47-105 47-41 0-77-16-105-47-28-32-43-77-43-137s15-106 43-137c28-32 63-47 105-47s76 16 105 47c28 32 42 77 42 136 0 60-14 106-42 138z'/><path d='m2356 3700c-47 6-93 44-112 68v-57h-148v602h159v-186c0-103 5-170 13-202 9-32 21-54 37-67s34-18 57-18c23 0 48 8 75 26l50-139c-34-20-69-30-105-30-9 1-17 1-26 3z'/><path d='m3116 3832c-6-25-16-47-31-67s-37-36-66-48c-29-13-61-19-96-19-63-4-168 21-198 70v-57h-148v602h159v-273c0-67 4-113 12-138s23-45 45-60 47-23 74-23c21 0 40 5 55 16s27 25 33 44c7 19 10 61 10 126v308h159v-374c0-46-2-82-8-107z'/></g></svg></template><template class=mhp1138_logo_xtube><svg class=mhp1138_xtube viewBox='0 0 518.9 263.4'><defs><linearGradient id=a x1=193.3 x2=193.9 y1=206 y2=206 gradientTransform='matrix(1 0 0 -1 0 598)' gradientUnits=userSpaceOnUse><stop offset=0 stop-color=#e5654a /><stop offset=1 stop-color=#c1222a /></linearGradient><linearGradient id=b x1=219.1 x2=222.3 y1=213.4 y2=213.4 xlink:href=#a /><linearGradient id=c x1=161.5 x2=391.1 y1=300.5 y2=300.5 xlink:href=#a /></defs><path fill=url(#a) d='M193.3 392c.4.4.5.2.6 0s-.5-.4-1 0z' transform='translate(-161.5 -165.8)'/><path fill=url(#b) d='M219 386.6c1.2 0 3-2.7 3.4-4-1.7 0-3.2 2-3.3 4z' transform='translate(-161.5 -165.8)'/><path fill=url(#c) d='M201.7 334a2.3 2.3 0 0 1 .4-2c-1.6 1.3-3.6 3-3.2 5a.4.4 0 0 0-.5 0h.3q-.7-.4-.6.4c-1-.2-5 5.6-5.3 6.4s.3.4.8.3l-4.6 4c3.5 1 0 1 .5 1s-4.4 1-2.2 3q-3.2.8-2 3c.4-.5.7-1.4 1.4-1-1.5 3.3-4.4 2-6.4 4 .5 1 1.7 0 2.6.6s-1.7 0-2.3.8.6 0 1.2.3q-1.7 4.7-3.8 2.2c.8 1 .3 2.5-1.2 4-1-.4.7-1.4-1-1.6l-7.5 8.6a101.8 101.8 0 0 1-6.7 9.3c4 .7 5-7 9.2-7.8q-8 4-3.2 7c-2 .5-2.7 1.7-4.3 3 1.8 0 2.4-1.4 3.6-2.5 2.7 4.8-2.6 3.6 5 5.7 1.4-5 7.4 0 8.4 1.2-.6 0-.7-1-1.2-1s1 1.4 2 2.2 6.5 2 6.5 2c-4.7.8 6 5 4 0-.5.3 3.3-.3 3.2-.3s-.4 0-.5 0l9.2-8.2s.4 1 1 1.6-1-2 1-.8q4-1.5 2.2-4.5c.7.7 0 .4 0 1 6-1.6 9.7.3 14-6.7q-1.4.5-2-.4a3 3 0 0 1-.6 1.5 2.4 2.4 0 0 1 .4-2 12.6 12.6 0 0 0 3 .2l-.2-.3c.6.2 1.2-2 1.7-1-1.3 3-24.6 22-22 24.6 1.7-1.3 5.7-5.6 8-5.4v.2l.7-.3a1.8 1.8 0 0 1-1-.3 8 8 0 0 0 3-3.2l-1.5 2.8q2 .4 2.8-2c2 5 5.2-1 4.6-2s-.8 1.5-1.7 1.6c-.3-2.4 3-3.5 2-5.7-.5.3-.2 1-.7.8s1-1.8 1.5-1.6a1 1 0 0 0 .4 1s5.3-6 2.4-6.3q.6 3.6-3.4 3.6c2.4-2.8 2.6-4.4 5-6.4a2.5 2.5 0 0 1-1 3.6c.5-.2 3.5-2.3 2.5-3.4 1 .2 1.6.6 1.4 2q6.6-3.7 4-8.4-.4 2.4-3.3 3.3c-2.2-1.4 8.7-8.3 8.5-12-.4 1-1 1-1.3.5 2.6-.8 9.3-14 9.3-13.2s0 .7.4 1c0-1.6.7-4 2-4-.2.4-1.4 1.2-1 1.6s5.3-3.7 4.5-4-.4 2-1 .5a14 14 0 0 1 1.7-3.5c-.3-1-.8 1-1.2.4s17-20.7 15.7-21.4-1 1.6-1 2.2c3.3-2 8-11.8 11.6-14.8.6 6.5 16.5 22.4 19.3 25.7l-2-1c-1.5 2 2.8 3 3.2 2.6l-.3-.5c1.4 1.5 2.7 2.7 3 5-.3.3-.6-.4-1-.6s8 12.8 9 13.6-.6-1 .2-1a7.3 7.3 0 0 1 1.4 2c.5-.3 0-.6 0-1s3.7 2 2 1.3c1.3-.8-2.6-4.6-2.6-5.5s-.3-.5-.5-1l-.4.3c-.3-.4 0-1-.3-1.2v-.2a3.3 3.3 0 0 1 0-1.3c.2.2 1 1.7 1.8.2h.3a2 2 0 0 0-.5.5q.7.3.6 0c2 5 24.4 39.5 29.8 39a.4.4 0 0 1 0-.5c-.4-.8 1-.3 1-1.3s1.2 1 .6 2.4q3-2.2-2.4-5v.5l-1.7-1a6.3 6.3 0 0 0 .5 1.6c-6-.8.6-3.4 0-3 .8 2-2-4.2-2-1.6-1-2-1-2-1.5 0a16 16 0 0 1-2-2.7 4.4 4.4 0 0 1 3 0s-3.2-3-3.3-2.8a1.4 1.4 0 0 1 .6.6q-1.4 1.5-1.4-.6a1.4 1.4 0 0 0 .7 1c0-1-.7-2.5-1.5-1.8l.5.4c-.8.4-1.2-.8-1.2-1.7s.7 0 .6-.3.4 0 1 .4-.5 0-.4.5 0 1.3.7.2-12-21-15-20c0 .7.6.8.5 1.8a6 6 0 0 1-2.8-3.2c.4-.5.6.4 1 0-1.5-1-4.5-2.4-3.7-4a.3.3 0 0 0 0 .3q.5 0 .2-.3l.2.3c.4-.5 1 .3 1 .2l.2.2c0 .2-.3.5 0 .7s.3 0 0-.4l.3.3c1-1-1-3-.8-4.4a1.5 1.5 0 0 0 .2.5c.4-.4 0-.4.6 0a3.7 3.7 0 0 0 1 1l.2-.4a1 1 0 0 0 .3.5c2.6-3 1.3 0 2.4 2.8 1.4-1 .5-.8 1.3 1 .7-.4.6-.3.6-.7s0 1.5 1 .8-3 1-2.5 0a1 1 0 0 1 .8 1.3c-.4 0-.6-1-1 0 1.8 2.4 5 4 4.7 7 .7-.4-1-3.3 0-4a.8.8 0 0 1-.7-.8v-.2a2.4 2.4 0 0 0 1.4 1 1.6 1.6 0 0 0 0-.4 2.8 2.8 0 0 0 1.5 1.5c0-1.5-1.8-1.3-2-2.7a1.6 1.6 0 0 0 .3 1.2q-1.7-.7-.5-2c2.6 2.2 1.5 5.7 3.7 5.3-.3 1 .4 1 1.2 1a4 4 0 0 0 1.4 4 .5.5 0 0 0-.7-.2v.2c.4.3-1-3.3-1-1.5a.8.8 0 0 0-.4.6c.4 0-1-2.6-1-1.7s4.7 2.7 3 4.8c.2.8.7.6 1 .7a1.5 1.5 0 0 0-.2-1c.7-.4.4-.8.3-1s.6 1.3 1 1.8-.3-.6-.6-.3a10.8 10.8 0 0 0 2 6c-.3-1 .4-.7.2-2 .5 1-1.5 3 1.2 3a1 1 0 0 1 0-1c1.7 2.3 2.8 4.4 4 6l.5-.5a2 2 0 0 1 .4 1.7c.7-.3 0-.8 0-1.2l.8 1.2.5-.6a2 2 0 0 1 .3 1.8c.7-.5-.3-1 0-1.5q7.6 4 4 7c2.6-.4 2 4 1.8 4.4s.3 2 1.2 1.4a2.2 2.2 0 0 1-.4-1.5c.8-.3.5.3 1 .7-2 1 4.8 6.6 4.8 7 4.4 1.4 1-1 1.4 1q6.6-.8 8 8.7c0-.5-1-1-.8-1.6a11.6 11.6 0 0 0 2.4 2.7c-.2-.6-1-1.2-.8-1.7s.5.3.7 0q-4.8-2-2.3-4a33.5 33.5 0 0 1 3 5.5c-.2-.5-.5-.7-1-.4a2.8 2.8 0 0 1 1.3 3 .5.5 0 0 1 0-.7 3.4 3.4 0 0 1 1.6 1.6 1.4 1.4 0 0 1 0-.5c1.4 2.3 8.3 13 9 12.5v-.3c1 .3 2 2.4 3.2 3a5.7 5.7 0 0 1-.8 0c1.6 3.3 6.4 12 8.3 11 0-.7-.7-1.4-.3-2s.2.8 1 .6a5.5 5.5 0 0 0-2-4.3 2 2 0 0 0 .3 2.8c-2-1.2 1-6.7 2-8.5v-.7c.4.2 1.5 2 2 2a.5.5 0 0 1-.2-.5 1 1 0 0 1 1 1 1.6 1.6 0 0 0 2.2 0 7.7 7.7 0 0 1-1.7-3 3 3 0 0 0-.5 1.5 2.7 2.7 0 0 1-.6-2 .5.5 0 0 1-.2.5c0-.7-.6-1.4-1-2l-.5 1c.8-6.7-2.7.7.6-1.4 0-2-1.5-3.3-2.2-4.8l-.5.6a14.4 14.4 0 0 1-1-1.6v.2a5 5 0 0 1-.3-1.2c.5.2.4.8 1.2.4-1.3-2-1-2.7-2.8-4.6a3 3 0 0 1 2.2 1 3 3 0 0 1-.7-2c0 .8 1 2.3 1.6 2.4s-2.2-4-2.7-4a2.5 2.5 0 0 0-.3 2 1.6 1.6 0 0 1-.2-1.6c-.6.6-3.8-7-3.8-7s1-.7 0-1.3a2.7 2.7 0 0 0-.2 1q-.7-1 0-1c-1-1.6-3-3.2-3-4.2s-1.3-1.4-1.4-1.6a.6.6 0 0 1 1 0c.3-.6-.7-.2-.3-1s.4 0 .6.5.3-1 0-1.4l-.5-.5-.5.3-.2-.4c.5.2.3-1 .8 0a.5.5 0 0 1 .5-.2c-1.7-1.5-4.3-12.2-6.6-7.4l-1-1.6h.2a4.2 4.2 0 0 1-1-3.3 14.6 14.6 0 0 0 1.2 2c1.7-1-.3-4.7-1.7-4.2v-.2q-.3.4-.5-.2a7 7 0 0 1 .8-.2c-.6-.3-.7.2-.6-1a2 2 0 0 0-.3 1c-.3-1.2-5-6.7-5-6.7a1.8 1.8 0 0 1 0 1c-1.3-1.2 1-2.4-.3-4-.7.4.2 1-.3 1.3s-2.4-6.4-3.4-7.2-1 1-.3 0-1.6 0-2-.8.3 0 .5-.2a.5.5 0 0 1-.4-.5c0 .3-1 .4-.8 0s-1 0-.7-1l-.2.5c0-.4.8-2 .5-2s.5.5 1 .2-1.6-1.6-2.5-.2a1.4 1.4 0 0 0 0-1c.2.4.5.6 1 .3s.3-1.2-.2-2L350 347q-1-1.6.6-1.6c2-.6 0-4.2-.8-3.7l-.4-.6.5.5c0-1-1-2.4-2-3a2.5 2.5 0 0 0 0 1 4.7 4.7 0 0 0-1.4-1.8 2.5 2.5 0 0 0 0 1 2 2 0 0 0-1.2-.8c-1.6-.8-1.8-1.5-1.7-1.4s2 1.8 1.4 1-2-9-5-8c0 .3-1.5-3.2-1.6-2.5s-.8 0-1.2-1a.7.7 0 0 1 .2 1q-1.4-1 .2-1.5a2.4 2.4 0 0 1-1-1.5 13.8 13.8 0 0 1-.2 1.7c-1.5-2-1.3-2.8-5-6.7a.5.5 0 0 0 .5 0c-.5 0-2-.5-1.6-1s-.6-.4-.4-1 .6 1 1 .7-1-4.4-1.5-3.8 1 0 0 .6-1.4-2-1.5-2 .7.3.3 1c-2-2.5-5-9-7.6-12.2 2-1.2-28.7-27.6-21-31.8-3-2 4-8 5-10a2 2 0 0 1 0 .5c2.7-3.7-1.4 1 3.4-6a1.3 1.3 0 0 1-.2 1.7 2 2 0 0 1 .5-1 1 1 0 0 0 .3 1.2c.4-.5 1.6-3 1-3.8a2.8 2.8 0 0 1-.3.8c-1-1 1-1.5.6-2 0-2.6 4.4-10 6-10.3h-.3c.5-.6 1.3-2.3 2-3.3.3-.8 1.7-4 1.4-2-.2.2 2.3-3.4 2-3.5s-.2.3 0 .5a11.8 11.8 0 0 1 1-2.5v.4a1.2 1.2 0 0 1 .2-1 1.6 1.6 0 0 1 0 .5c-.5.6 2-4 2-3s0 0-.4 0 .2-.6.4 0a18 18 0 0 1 2.5-4.5 1.7 1.7 0 0 1 0 .5c.6-1 3-3.4 3.3-4.5.3 1-2 7.5-2.6 8.4.6-1 1-2 1.6-2.5s-1 1.2-.7 1.8a32.2 32.2 0 0 0 2.3-4.6c.2.3-.4.7 0 1a42 42 0 0 0 3.6-9 1.2 1.2 0 0 1-1.3.8 1.4 1.4 0 0 0 .3-.7s-1.5 1-1 1.6a2 2 0 0 1 .6-.7c0 .3-.5 1-.5 1.4a2.5 2.5 0 0 0-2 1.3c1-2.8 2.3-6 4.6-7q-.4.2-.3-.3v.3q-.5-.7.4-1c-.4-.8 5-8.8 5.6-9.6s.7 0 .7.5 2-6 3-7.5.7 1.4 2-1.5l-.6.2c-.6-.7.4-1 1-1.4v.4q-.3-3.4 2.5-3.5c-.7.7-1.5 1.6-1 2 3-3 1.7-5.2 2-7.7-18.3 7.7 4.7 11.3-5 .3-1.2.2-.2 2-1.4 3-.8-1 1.6-2 0-3 0 .5-.6.7-1.2 1a28.7 28.7 0 0 0 3.2-6.4c-.8-.2-1.3.4-2.3-.4-.3.7.8.5.7 1.3-2 1-2.5-4-3.4 5.8.5 0 .7-.6 1.3-.3a6 6 0 0 1-.3 3c-1-.6-.3-1.2 0-2s-5 2-1.8-.7c-.7-.7-.8 0-1 .3-3.7-3 8.3-7.4 2.7-10.4.2.6-.5 1 .6 1.7s-1.3-.3-1-.7-7 5.8-8.6 7.2 0-.7-.7-1l-1.6 2.8c1.4.2 1-1 1.7-1.7 1 1 0 1.6-.5 2.4q-5.5-2 1.4-7.8c1.4-1-4 4-3 .7-.5-.3-.6.6-1 .8s0-1.6 1-1.3a1.2 1.2 0 0 1-.2-1.7c-7 10.7-9 11.8-15.6 8 0 1.4-1.3 1.7-1.3 3-.7-2 1.2-3.4 2-5.5-1-.5-1 .3-1.5.4s1-1 0-1.8a1.2 1.2 0 0 1-1 1.3c-.4-.2 0-.4 0-.6a3.5 3.5 0 0 0-3 3.5q.2-1.7-1-1.3c1.2-2.4 7.8-12 5-15.3-1.6 0-2.6 1.7-3.3 3.7l.6-1q0 1 .7.7a1.4 1.4 0 0 0-.2.5h.7a.8.8 0 0 0-.3 1l-2.7 4.6c-2.5-1.7-2.3 6.2-4.3 6a2 2 0 0 0-.2-1.2c-2.3 2-1.5 3.5-1 3.8s.4.8-.2.8.5.7-.2 1.2-.5-1-.4-1.2-3 8-3.4 8.5-1.5-.5-1.7.4.6-.6 1 0-2.7 0-2.2 2c-2-1 2-1.7.8-3.3 0 .5-3 3.2-1.2 4q-1-.4-1.5 1.5 1-.3.8 1a1 1 0 0 1 1-.7c0 .7-7 2.7-4.2 4s2.4 4.4.6 4c0-.8 1-.8.7-1.6-2 .2-1.3 3-3.6 2.7 0-.5.8-.4.4-.7s-.8 1.3-.5 1.6a1 1 0 0 1 1 0c0 .2-2.3 5.5-4 3.2q3.2-.2 1.3-3.3c-1.2 2.4-2.4 3-3 5.3a1.8 1.8 0 0 0 2.6-1.4q-3.7 3 .6 3.3c-2.5 2.2-5.2 10-9.4 11a.6.6 0 0 0-.5-1.2c.3 2-6 10-6.4 10.3a2.7 2.7 0 0 1 1 0c-1.4.4-3 1.6-2.3 2.7s.4-1.4 1-1-.2 4-.7 4.4a1 1 0 0 1-.6-1q-.4.3-.5-.7a3 3 0 0 1-1.4 2.7c-.7 0-.2-.4 0-.7h.3c0-.6-.5-1.2-1-.6s-1.4.3-2.2-1.6l-4-4.4v.5c-1-.7-.2-1.7-.5-2.2s-.5 1-1 .6h.2c0-.3-3-3-2-3.5s.6 1 1 .7a7.8 7.8 0 0 0-4.8-2.6c.3-.4 1 0 1.5-1s-1.2.5-1.6 0 .3-.3.7-.5-2.5-1.5-2.3-2-1.7-2.4-2-2.6 0 .6 0 1c-1-3-4.7-5-7-7h.3l-1.7-1c1-.8 1.3.7 2.6.6-4-5-9.8-9-15-13q2.8-1-2-3.6c-.5-.7-1-1.3-1.7-1s0 1.2.4 2.2-.5-1-1-.4 3 2.6 1.6 5c-4.2.7-3.7-3.5-4.3-5.7 1.2-1 1.3.8 0-.5a2.5 2.5 0 0 1 0-.6c-.3.4-.4-1-.8-.8a9.2 9.2 0 0 1-2-2h-1.7a1 1 0 0 1 1.2-.3c-.3-.4-.5-1.5-1-.7s3 4.6.6 4a1.6 1.6 0 0 0-.3 1c-.2-1-.3-1.7-1-2a.8.8 0 0 1-1 1c.4-1-3-1.6-3.7-2s0 1 0 1.3-.5-2-1.5-2.4a9.3 9.3 0 0 1-.2 1.4 8.4 8.4 0 0 0-2.5-1c.2 6.5.5.4-1.5 2.3-.3.7 1 .6.6 1.2s-1-.4-1 .2c1 1.8 1 1.8 3 3.3q-2 0-1.5 1-9-3.2-11.2-14.2a8.4 8.4 0 0 0 0 1l-1.5-2q2.4 2 0 2.5a1.2 1.2 0 0 1 .6 2c-.5-.7-6.5-7-4.8-5.7a6.6 6.6 0 0 1 .8 1.6 14.3 14.3 0 0 0-2.3-2.5c.6.8 1.4 1.8.6 3a.8.8 0 0 0-.8-.8 9.6 9.6 0 0 1 1.4 3.7c-.4-.4-4.6-6.6-6-5.7v.3c-.6-.5-1.2-1.5-1.5-1.3 16 40 1 5.3 2 10.8a77.4 77.4 0 0 0 2 12.8c-1 0-.5-.8-1-.8l-.8 1.5c-.5-1-1-1.7-1.6-1.5 3.8 5.2-2.2-.8-1.5-1 5.4 7.6 2 21.2 2.2 25q0 2 1 1.5a3.3 3.3 0 0 0 2 3 1.7 1.7 0 0 0 0-.5c2.3 3.3 1.6.7 1.3-.4s.8 0 1.3-.3c-1.6-1.5-2-1.5-3-3.3.4-.6.6.5 1-.3s-1-.3-.5-1c2-2 1.7 4 1.5-2.3.5-.4 2.3 1.5 2.5.8a1.2 1.2 0 0 0 .7.5 1.5 1.5 0 0 0 .2-.8c.3.7.3 1.6 1.3 1.8 1.2-1.4.6-1.3 1.5 0 2-1.5.4-.7 1.5 1a1.4 1.4 0 0 0 .5-.7 2.2 2.2 0 0 0 .4 1l.6-1a9.3 9.3 0 0 0 .8 2l1-1.7c0-.4 0 3.5 1.2 2.4s3 4.8 5.8 4.3c1.5-2.5-2.2-3.4-1.5-5s.5 0 .8.4 0-1-.5-2q2.5 2 .6 2.5c5.3 4 11 8 15 13-10 1.2-4.5-9.5-10-5.6.5-1-1-.6-.5-1.4l1.2.6q-1 .6 1 1.6c.2-.8-1-.5-.8-1.3 3.6 1.5 6 5.6 7.3 8s-.4-2 1.6 1l5 5c1-.4-.4-1 .4-1.4a2 2 0 0 1 1 2.5.5.5 0 0 0 .5-.4 2.7 2.7 0 0 1 0 1.4c.2-.4 0-.7.5-1a1.4 1.4 0 0 1 1 2c1.6-1.5.6.3.6.7s1.3-.5 1.7.3-1.6 0-1.8 1.2l2.2 1.3c-1.5 1 2.4 1.4 1 0 1.3 0 .7.7.2 1.2s.4 1.2.7.8 0-.6 0-.6a4.4 4.4 0 0 0 1.3.5q-1.4 1.4 1 1.8s.7.7.8.5c-.2 0 .5 1 1.3 1.4s.2 1 .3.2v.2c-.4.6.4 1.2.7.7 8.2 9.2-11 24.4-16 33a8.2 8.2 0 0 0 1 0c-1.4 2-2.5 3-4 5.3a1 1 0 0 0 1-.7 1 1 0 0 0-.4.6 1 1 0 0 1 1 0c-.3.8-2 2-2.6 1.7a1.5 1.5 0 0 0 .5-.5c-1.5-.6-1 1-1.5 1-2.3.3-6 6.2-6.5 8a.8.8 0 0 0-.8 1c-.6.6-2.3 2-1 1.5s-1.8 2.4-2 2.4.3-.6.5-.5a6.4 6.4 0 0 0-1.5 1.4h.3a.7.7 0 0 0-.5.3h.3c.3-1-2 2.3-1.6 2s0-.3 0-.4-.4.2 0 .3a10.5 10.5 0 0 0-2.4 2.7h.2c-.4.7-1.6 3.5-2.2 3.8 1 0 1-1 2-1m-2 3.7c-.7.7-1 1.5-2 1.5a.8.8 0 0 0 0-1.2s-.2.6-.4.5 0-1.5 1-1a1 1 0 0 0-.5.4m127-110.5a1 1 0 0 1 1-1.5l-1 1.4s.3-.7 0 0zm-142.8 8c0-.3-.5-1 0-1.2s1 1 0 1.5 0-.4 0 0zm36 14.7v-.2q.2 0 0 .2zm14.7 15.4a1.4 1.4 0 0 1-1-1c.5 0 1.5 1 1 1zm-.6-52.7c0 .2-2-.5-2.4-.7 2-1.7 7.4 2 8.2 6-2-2-4.3-3.3-5.7-5.6-.3.4 1.2 2.4 0 .2zM198.6 337c0 .3-.3 0-.5 0s.6 0 .6 0zm-1.2 1a.2.2 0 0 1-.3 0zm15-19.3l8-9.4s0 .5-.4.5.4-.5.5-.3zm172 94.3a1.2 1.2 0 0 1 .3 1.3c-.5 0-.4-.7 0-1.3s-.4.5 0 0zm-1 .7zm-.3-6.4l-.5-1a2 2 0 0 1 .7 1zM376 392q.8.5.4 1t-.4-1c.2.3 0 0 0 0zm-3-6.8l-.4.6-.6-.5a3 3 0 0 1 1 0c-.2.3-.4 0 0 0zm0-2a2 2 0 0 0-.2 1 6 6 0 0 1-1-2.5l1.2 1.6c0 .3-.3-.5 0 0zm-2-.8c2 2.3.5 2.5 0 1.7a.7.7 0 0 0 .7 0q-1-1-.6-1.6c.4.7 0 0 0 0zM358 359a6.5 6.5 0 0 0 .8 1q-1.4 0-.8-1c.2.3 0 0 0 0zm-.2-.6c0 .2-.4.3 0 0zm-58-22c.6-.5 1 0 1 .7a1.5 1.5 0 0 1-1-.4c.2 0 .4.3 0 0zm29.6 20a.5.5 0 0 1 .3-.6q.4.6-.3.5s.2 0 0 0zm56.8 59.2c-.5-.7-1.4-.5-2-2q.6 1.3 1.4-.3c-.5 1 .6 2 1.2 2.6a.8.8 0 0 1-.6-.7zm.8 2c-.2-.2 0-.4.3-.6a1 1 0 0 1-.2.8zm.4-1.6a1 1 0 0 0 0 .4 1 1 0 0 1-.5-1.7q1 1 0 1.2h.3z' transform='translate(-161.5 -165.8)'/><g fill=#fff><path d='M146 53.2v21.5h29v78.8l3 3a3 3 0 0 1 1.2 1l1.4 2c3.8 5 7 10.2 11 15s5.5 8.2 8 12.6l1.4 2.6 1.5 1.6V74.8H231V53.2h-85zm123.3 0v116.3c0 10.8 5.5 14.6 14.2 14.6s14.2-3.6 14.2-14.3V53.2h26V168c0 24-14 38-41 38s-41-14-41-38V53.2h27.5zM424.7 88v5c0 15.5-5.5 25.4-17.7 30.4 14.7 5 20.5 16.4 20.5 32.3V168c0 23.3-14.2 35.7-41.7 35.7h-43.3V53H384c28.5 0 40.7 11.4 40.7 34.7zM370 74.7v39.8h10.7c10.2 0 16.5-4 16.5-16V90c0-10.7-4.2-15.4-14-15.4H370zm0 61.4v46.5h15.7c9.2 0 14.2-3.7 14.2-15v-13c0-14-5.5-18.4-18-18.4h-12zM471.4 117H509v21.5h-37.6v44H519V204h-75V53.2h75v21.5h-47.6v42z'/></g></svg></template><template class=mhp1138_svg_hotspots><div class=mhp1138_hotspots><svg viewBox='0 0 1000 100' preserveAspectRatio=none><defs><clipPath id=hotspotsClip clipPathUnits=userSpaceOnUse><polygon/></clipPath></defs><g clip-path=url(#hotspotsClip)><rect class=mhp1138_hotspotsBg x=0 y=0 width=100% height=100% fill=rgba(33,29,27,0.58) /><rect class=mhp1138_hotspotsFill x=0 y=0 width=100% height=100% fill=#6d6d6d /></g></svg></div></template>";
6MHP1138.skinsMarkup['css'] = "@font-face{font-family:'desktop-icons';src:url(data:application/x-font-ttf;base64,AAEAAAALAIAAAwAwR1NVQiCMJXkAAAE4AAAAVE9TLzJDWUuvAAABjAAAAFZjbWFw5ALluAAAAjgAAAJ6Z2x5ZmVfToAAAATgAAAOCGhlYWRjnq2PAAAA4AAAADZoaGVhFAYMSQAAALwAAAAkaG10eLLO//0AAAHkAAAAVGxvY2EeoiHSAAAEtAAAACxtYXhwASUBNgAAARgAAAAgbmFtZY7SrP4AABLoAAACUnBvc3R42UwNAAAVPAAAAPYAAQAAB9AAAAAADDX////+DDUAAQAAAAAAAAAAAAAAAAAAABUAAQAAAAEAAF/nEI9fDzz1AAsH0AAAAAB8JbCBAAAAAHwlsIH////vDDUH0QAAAAgAAgAAAAAAAAABAAAAFQEqAAYAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKADAAPgACbGF0bgAOREZMVAAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAEIhAGQAAUAAAKbBXgAAAEYApsFeAAAA8AAYgIEAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAQOAB4BQH0AAAALQH0QARAAAAAQAAAAAAAAAAAAAH0AAACMT//ws7AAALOwAAB9D//wcpAAAGWQAABu0AAAhNAAAJRwAAB9AAAAae//8MNQAADDUAAAg5AAAKagAACmoAAApqAAAH0AAAB9AAAAAAAAUAAAADAAAALAAAAAQAAAF6AAEAAAAAAHQAAwABAAAALAADAAoAAAF6AAQASAAAAAQABAABAADgFP//AADgAf//AAAAAQAEAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAEAAAAAAAAAABQAAOABAADgAQAAAAEAAOACAADgAgAAAAIAAOADAADgAwAAAAMAAOAEAADgBAAAAAQAAOAFAADgBQAAAAUAAOAGAADgBgAAAAYAAOAHAADgBwAAAAcAAOAIAADgCAAAAAgAAOAJAADgCQAAAAkAAOAKAADgCgAAAAoAAOALAADgCwAAAAsAAOAMAADgDAAAAAwAAOANAADgDQAAAA0AAOAOAADgDgAAAA4AAOAPAADgDwAAAA8AAOAQAADgEAAAABAAAOARAADgEQAAABEAAOASAADgEgAAABIAAOATAADgEwAAABMAAOAUAADgFAAAABQAAAAAAAAAZgCWAMYA+AGGAZwBsgHAApQC6gNaA8QD2APuBAwFUgXGBfYGpgcEAAMAAAAABwkH0QATACMARgAAASEiDgEVERQeATMhMj4BNRE0LgETFAYjISImNRE0NjMhMhYVASEiDgEVFBYyNjU0NjMhMhYVERQGIyIGFBYzMj4BNRE0LgEFB/xeK0grK0grA6IrSSorSAQcE/xeFBwcFAOiExwBNfxeK0kqIC4gHBQDohMcHBMXISEXK0grK0gGcipJK/rKK0grK0grBTYrSSr6LRQcHBQFNRQcHBQB/CtIKxcgIBcUGxsU+soUHCAuICpJKwU2K0grAAP/////CMYH0QARABUAGQAAJQEuASIGBwEGFB4BMyEyPgE0JSERITUhESEIsvwtE0NNQxP8LRMmQyYHpyZCJ/ws/uIBHv7iAR7WBrIhJych+U4hTUImJkJNaQEejwI8AAQAAAAACzsH0AAFAAsAEQAXAAApAREhESEBIREhESEBESERIREpAREhESEJxP6JAu7+ifkq/on+iQLuCE3+if6J+qH9EgF3AXcC7v6J/okBdwF3AfQBdwF3/RIBdwF3AAQAAAAACzsH0AAFAAsAEQAXAAABIREhESEBIREhESEBESERIREpAREhESEJxAF3/RIBd/Y8AXcBd/0SCE0BdwF39MUC7v6J/okC7v0SAXcBd/6J/okH0P6J/okC7v6J/okAAAAD//8AAAfQB9AAGgBIAFUAAAEiBwYABwYQFxYAFxYgNzYANzY1MTYnJgAnJgMGJicmNjc2NzY3Ni4BBwYHLgEnNjc2NzYXFhcWFxYPAQYHBh4BNzY3FhcGBwYTDgEuAj4CHgIGA+fLubT+7ExPT0wBFLS5AZa6swEVTE4BTkz+67O63kh3Hh4WMRs4IAUJDSEUMiUEFAQtMUJALTE1JSoMDR00OBIMByAXNi8RDTVAWuwgUE02DRxAUU01DhwH0E9M/uy0uf5qurP+60xOTkwBFbO6y8u5tAEUTE/5zBkUKSuGgUmETBAaHgMLICIJJAgtISwPDAYGGRwwOEyNlTUmKAMQJS4bGTczSAOqHBIVOEpKNxMVOUtJAAAAAAIAAAAAByoH0AACAAYAAAkBEQUhESEF3PokByn+swFNA+j8GAfQU/jWAAAAAgAAAAAGWQfQAAMABwAAAREhESERIREB9P4MBln+DAfQ+DAH0PgwB9AAAAABAAAAAAbuB9AAAgAACQERBu75EgPo/BgH0AAAAgAA//8H0AfQABQAiAAAASInJicmNDc2NzYyFxYXFhQHBgcGJREnJicmJy4BNzY3Nj8BJwcGBwYHBicjJicmJyYvASEHBgcGBw4BJyYnJi8BBxcWFxYXFgYHBgcGDwERFxYXFhceAQcGBwYPARc3Njc2NzYXMRYXFhcWHwEhNzY3Njc+ARcWFxYfATcnJicmJyY2NzY3NjcD6FtNTCwtLSxMTbZNTCwtLSxMTQONOUIbLBofIwIBEgofGr81PhwtJCoqASscGBMMFhT+8xMWDBQYHFYpJC0cPja+Gh8LEQECIx8aLBtCOThCGywbHiQCARIKHxq/Nj4cLCQqKyscGBMMFxMBDRMWDBQYHVUpJC0bPza/Gx8LEQECIx8aLBtCApstLExNtk1MLC0tLExNtk1MLC3GAQ4TFgwUGBxWKSUsHD42vxsfChIBAhISHhosG0I5OkEbLBofIwIBEQsfGr81PxstJCpVHRgTDBYU/vMTFgwUGBxWKiQtHD02vhofChIBAhISHhsrG0I5OEIbLBofJAIBEgofG782PhwsJCpWHBgTDRYAAAEAAP//CUgH0AAxAAABIQkBISYnJicmIyIHDgEHBhAXHgEXFiA/ARMHBiMiJyYAJyYQNzYANzYzMhcWFxYXFggEAUT90f34AUMiPEtpfZ+QhH7FNTg4NcV+hAEghEW+XNXm2MW//tpQVFRQASa/xdiXnJCIgGtmBO/9rAJUYlFlOEQ1M7h4fP7yfHi4MzU1HP7mKFxPTAEVs7oBlrqzARVMT0E8bmeFgQAAAAACAAAAAAfQB9AALABFAAABPgEzMh4BFA4BIi4BNSUGIyIuATQ+ATMyFhclNTQ+ATIeARQOASMiJicFFAcTIgcGAAcGEBcWABcWIDc2ADc2ECcmACcmBGoeUC05YDk5YHJgOf5wNE45YDk5YDksUB8BfDlgcmA5OWA5KUka/noF9cu5tP7rTE9PTAEVtLkBlrm0ARVMT09M/uu0uQMHIiQ5YHJgOTlgOcgtOWByYDkiH8gZOWA5OWByYDkdGs0eDwQLT0z+67S5/mq5tP7rTE9PTAEVtLkBlrm0ARVMTwAAAAH//wAABp8H0ABDAAABIgYHATY1NCcBHgEzMjc2NzY0JyYnJiIHBgcGFRQXAS4BIyIHBgcGFBcWFxYzMjc2NwEGFRQXFhcWMjc2Nz4BJyYnJgVsNF8o/asHCAJZJ18zVEdFKCoqKUZHpkdFKSoH/aMnWzFTR0UoKiooRUdTMzAuJwJYByooRUenR0UoKgEqKEZHAmQhHgF9HCUgJwGBHiEpKUVHp0hFKCoqKEVHUyQc/n0cHiooRkenR0UpKRAQHv5/GSVTR0UoKiooRUenR0YoKgAAAgAAAAAMNQfQAAMABwAAMREhEQEhESEMNf6J9rkJRwfQ+DAGWfseAAIAAAAACr4GWQADAAcAAAERIREDIREhAXcJR/r4rQdTAXcE4vseA+j9EgAAAQAAAAAIOgfQAAkAAAkBAwElCQEFAQMEHQKKrAI+/Qv+2f7Y/QsCPqwBiP54AuQB8UECuv1GQf4P/RwAAwAA/+8KWwfQAAUA0QEpAAARIQERASEBMx8pFRcVDy4jByMnMz8vPQIvMCMnIzczAzMfERUPFysBJzM/DzUnNS8RNzMCLAKX/Wn91AZODhtDWVgMDFULDEMLFkIKHigIChMSCSQYCAgHEAgGEAcHDi0RBAYSERsJCQEGDQMCAwMGLAYEFxgUCAcdEAcICAgHCRAbNzIKSxYMCwsiGBgMPBgNDA0lDgxbQw0cKAEXIUIKFRULHwoUCgoeOi4kGQkICQ8JGAcYBxAPDggNDgYTLQQGBAYfDBcHAwsBBwMEBwICDgQCCQIYGgQFBAQ9DAcHBgcNCBwHBxAHLyIJEgcJBS0JCQoJRBQKHgsKChULWBUKDAENKA0oQT4XCxdLKC0ICR8iEBIKBQQBCwMFEgsGBg0OFwkJGhMzCjdJJTMNGxsNDwMdRSgfGxMMBhcWFAIECwEEBAIGAgIEAQcUGhwBBwYxCA8oEk8CDAWkAb35DgG9BaQBBg8YBAMgBQUhBwsoBxQgBwgREgckGwoIChIKChQKChRNIQsLLjFgMWYODE9ASwwNDAwYdgwLLCwfCgooFAkKCQoJCREbMCcHLw4FBwYRCwkFFgcEAwUKAgMQBgLeAQcCAgQBBwMFAwIKFBYSDwQGBQsFEgYRBwsODQcNDwYXPggHCAg8Gz4aCi8KHB4nPQoWOgoTOAkJGgk9MwkJDwdWDgcIBggOBhsHBgsHIRcECwcECBYDBQQEFwUDBwUBAgMBCQHe/dYDCxEJAwknGicJCCQyHiwkGDElDD0LDSsWCgoUEhsICRcPIQUcGwoIAgMD3gkLDA4LCAQRFhsFBBgECQ4nBAccBAUJBQ0bGxYFAwQYAgYLBAnfAAIAAAAACDcHYQAFAF4AABEhAREBIQEzHxIVDxcrASczPw81JzUvETczAiwCl/1p/dQGIg0oQT4XCxcsHygtCAkfIhASCgUEAQsDBRILBgYNDhcJCRoTMwo3SSUzDRsbDQ8DHUUoHxsTDAYXFhQCBAsBBAQCBgICBAEHFBocAQcGMQgPKBJPAgwFpAG9+Q4BvQN4AwsRCQMJFhEaJwkIJDIeLCQYMSUMPQsNKxYKChQTGggJFw8hBRwaCgkBBAPeCQsMDgsIBBEWGwUEGAQJDyYEBxwEBQkFDRsbFgUDBBgCBgsECd8AAAAEAAAAAAkdB2EABQAJAA4AEgAAESEBEQEhJQcBNyUXAScBFwEnAQIsApf9af3UCQK5/Xa6Ad7G/UzFArPG/UzFArMFpAG9+Q4BvcLHArjHAsb9S8YCtcb9S8YCtQAAAAAGAAAAAAdcBgYAHwA9AEoAVwBoAHUAAAEhIg4BFREUHgEzITI2NxM2MhcTHgEzITI+ATURLgITFAYjISImJwMuASIGBwMOASMhIiY1ETQ2MyEyFhUFIg4BFB4BMj4BNC4BAyIuATQ+ATIeARQOAQEiDgEVFBYXFjI+ATU0Jy4BAyIuATQ+ATIeARQOAQa1+lYlQicnQiUBkCxGE3UdbB11E0YsAZApRSgIMEYaJB7+cBIaBnUSWWZZE2wGIRP+cBohIhkFqhoo+3I+Zzw8Z3toPDxoPSVCJydCSkEnJEECzj5nPDwzNXtnPCAfaTklQSgoQUpBKChBBgYpRSj8nSlFKDAsASM7O/7dLDAoRSkDYylFKPwHGygXEwEkMTs7Mf7cEhgkHwNjGigkHsg9a4NrPT1rg2s9/oApRVFFKChFUkUoAYA9a0I9bB8hPWtBPTc1Qf6AKUVRRSgoRVFFKQAAAwAAAAAHIAXdACAALgA8AAABISIOARURFB4BMyEyNjcTPgEyFhcTHgEzITI2NRE0JiMBIi4BND4BMh4BFA4BIyEiLgE0PgEyHgEUDgEjBrj6UxsuGxsvHAGNHzMMcw9BUEEPdAszHgGNKz09K/uzMlQxMVRkVTExVTIC8DJUMTFUZFUxMVUyBdwdMB38mh0wHSQeASElLi4l/t8dJT4sA2YsPv0lM1doVzMzV2hXMzNXaFczM1doVzMAAAAAABAAxgABAAAAAAABAA0AAAABAAAAAAACAAcADQABAAAAAAADAA0AFAABAAAAAAAEAA0AIQABAAAAAAAFAAsALgABAAAAAAAGAA0AOQABAAAAAAAKACsARgABAAAAAAALABMAcQADAAEECQABABoAhAADAAEECQACAA4AngADAAEECQADABoArAADAAEECQAEABoAxgADAAEECQAFABYA4AADAAEECQAGABoA9gADAAEECQAKAFYBEAADAAEECQALACYBZmRlc2t0b3AtaWNvbnNSZWd1bGFyZGVza3RvcC1pY29uc2Rlc2t0b3AtaWNvbnNWZXJzaW9uIDEuMGRlc2t0b3AtaWNvbnNHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuaHR0cDovL2ZvbnRlbGxvLmNvbQBkAGUAcwBrAHQAbwBwAC0AaQBjAG8AbgBzAFIAZQBnAHUAbABhAHIAZABlAHMAawB0AG8AcAAtAGkAYwBvAG4AcwBkAGUAcwBrAHQAbwBwAC0AaQBjAG8AbgBzAFYAZQByAHMAaQBvAG4AIAAxAC4AMABkAGUAcwBrAHQAbwBwAC0AaQBjAG8AbgBzAEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAAcwB2AGcAMgB0AHQAZgAgAGYAcgBvAG0AIABGAG8AbgB0AGUAbABsAG8AIABwAHIAbwBqAGUAYwB0AC4AaAB0AHQAcAA6AC8ALwBmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQAAAAIAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgAEY29weQVlcnJvcg9mdWxsc2NyZWVuLWV4aXQKZnVsbHNjcmVlbgRpbmZvBG5leHQFcGF1c2UEcGxheQdxdWFsaXR5BnJlcGxheQtzaGFyZS1yb3VuZAVzaGFyZQpzaXplLWxhcmdlC3NpemUtbWVkaXVtBHN0YXILdm9sdW1lLWZ1bGwKdm9sdW1lLWxvdwt2b2x1bWUtbXV0ZQh2ci1jbGVhcgJ2cgAAAAA=) format(\"truetype\"),url(data:application/font-woff;base64,d09GRgABAAAAAA6IAAsAAAAAFjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIwleU9TLzIAAAFEAAAAQQAAAFZDWUuvY21hcAAAAYgAAACgAAACeuQC5bhnbHlmAAACKAAACZ0AAA4IZV9OgGhlYWQAAAvIAAAAMwAAADZjnq2PaGhlYQAAC/wAAAAeAAAAJBQGDElobXR4AAAMHAAAAEQAAABUss7//WxvY2EAAAxgAAAALAAAACweoiHSbWF4cAAADIwAAAAfAAAAIAElATZuYW1lAAAMrAAAATQAAAJSjtKs/nBvc3QAAA3gAAAAqAAAAPZ42UwNeJxjYGRgYOBiMGCwY2DKSSzJY+BzcfMJYZBiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCAClZBUgAeJxjYORoYZzAwMrAwDSbtYKBgVECQjMfYEhiYgGKMrAyM2AFAWmuKQwODxgfiLBfAHK3sF9kEATSjCA5ALkACo8AAAB4nO2R7Q3CMAwFLzQt9JMCGYNBGIhfTJtNil+e2AJL51MsJ4psoAe64BlkSB8SindUU6t3TK2eebWerHotxxE5Kcc5t3yK3hwvDpy5MMa9mYWVjSs7N+48KNE48I9FKf1ORbM0bbong9wZbalmo3nX3miDdTDIZ4N8McijQZ6MNltng7wY/a6uBnkzyFeDvBvkm0G+G+SHQS6G8gWUmi58eJy1F1mMHMW1q4+qvubumZ6d7umZnqvn3p2dnZlde2fs3WUvew87PmBjBE4gPrAVIRJjKxwBxUR2JCv+SZByCIVEQSLkhzWRbQksRbFBkERGShCJwEgoIkhGJgdB9nqnnaruWTDgfGZmuvq9V++9eke9VzUUQ+EPEtDrVIhKU1MUBcyUF4QDigHq5mAHNAJDVRBSYNpM5TDcxMRI2OVRIoPNRo8SwBwpqETqayIcWr2rNFPCP+bp0myxNMPqodW7FF1XmKdDOmjg2dlispp0cT2kmqbq8MMHirOllVddWa6JuVYqRIxrkBGsYqqaTKqKpikrryo6VoH5Md9MiWJu4A9/AfsSoMJUH0VlQRWkIAJwzZuhrBkwG/jhn1+thCbmJ0L4lZvIoWdy49Zq2X4XGOR5Az5vWpZ5bcGcH8/lxuf3A+P79CjFklhJ69FFiqMkvIZKUQUQwNqA6YxkCLgU4Xf2cfqKffxa0T5OIH6evFd+1g2Cw+AwmbGPEwh8REaXeiv9Pc230O9KfTzqyvPz5P3ReVczfcXVSGB00aWQEavHMcL5vojXiFEz1A68QgpBCkG/GqHUSLLVpFrNRq1p5Sgrx8CclWu2nG8VIIiqwHIQNUK+PgARNAAmRFQMhbygSndog4bM3187c8r+YG5xcQ4op86AH55dBuG5BbAwZ19ePntp5rBhRGracJITPKYymGUVtlIb31ipNbJF2RMfGg7KKKk2+wOexsYvf5DcMt/06Bu3zje8Orq4OGd/cOqMfd/ZZfvy3MLCHAgvn30NrwaUucVrv+9TCqXvPj57dM4fMxgpmRIyfMUs+2QI+/SB4bkTP2jk8ow/W9X6WvUZ5lk9GB7etKkVCo9sniWhp51aKOLY0BSkKAEEOBxq7q2VDCrYy2CeeX81ii5uu/rGGi9cwrwMhXAUndyYAfCRLcMlW0YXrw64D2YDDu8VRy/RCq9cC7q6HD03bjj5UKhjJBsWjvkQCfIgibGCow6zAUK0qiTUzQ3AIjQErTQh5vqB6eBe4GLITY7D4gMBBzOAi6luLtWaw5IApoN3gIu1nFV6CWfe3zU/V65UynPzv1kDmBMj41o5lkjTICgmYucaHb2SKRZBSY+G5Ihi/zsUkZWovrOQqeid5kuxhBQAdDoRK2vjI8NYUjMyPclmRy9niiVHUA0BjyMY34EFtQ3Nc9pNgvSPP2OCA1wA3rWVsmW8EhYQg4AOBg1nqXVjPSMDEjFyg4aN3BH/rIlFbGKbmNgT1Eo9G2MJ10atZ+NObKIn4uTwxg1hBuepRqpSAKYTrHQKB55Uj4GDmNwAQgj3Qad4/E4p1QfddPAsuK37evcqmEiNbt7/yFMnjz56vjE83Dj/6FGQPDr50p1/fu/N8+fsv27Zvn0LyJ07/+aTPzl57LEDe9gPu8/R27+69WvDtzXqp488bP/r4SOn642Gbr+Xv3PR2f698locG/363ice/3Qfkz1VpiaxtR1QHzSA4gWpKmhksYFVMERoETXbwIA7l07lLE5BoS+2A7/jD3ufsaUysntkZPcDu0fs+4cWHHikvCUBHnZoGCnMxuxvcf8h1X/Zqf4wqX5cnWGC2ZdPnWFQKrPG/UrFgVKJV/rW9MZjfzB8rOTy2vfdSg+pJ9LD4FPYvwlSMbjB43PIArjHD5K9O0QSkyI7Pqyo+ARIO7BC0uAwAELHyKCz9wkzd3Do7nz3V4inl6y769unJ/PFYmFq+pfTk4Ui6v7c2lXb5tDyk9Pb6gNVi74DEfgZQgTF/NQ0fa9pgEf0bNICjxtmoYDnZtYEMrr9iG4QLsxfKPj9hv3tvuwnCp+ZnsoXezmTG2v9pEZ6CW4ocsM+/vEZYZr0Erh03XD5xJfg0qd9hyFnw2FheuXqr9E2cJh997rBvN8N9voOvw7rFEjfYUBWABxg2Dj9vefoTley/2K/2ZXoznPgmH2E/hv45xh9tjs1Zvu6OtZO3fhQ3OWcRa+DAkWR8weYoJ4ohNWwr5pGaau+ob9N9w+krXSrztQTgbBPLQFM9TWsRn+gVafL9JPd/d0/wQWvNrF0hyzvkOQJKTIuGnleDAWFTJTnkZ+HfoS8lQALgwFNEAD0MDTDwDJk1ajCo7gf8ZhN8GutQXFzRJakVDQqj0Y9sifrlXdNePQ8UM1xMRyWEqIiisa6aqZP4AWfEEVR5Pd5eY8XhiosZGFCVhEjAcSwiKa9LC3Q0RjLsWxbRniHeHgdIT/qTwlBJHAVQRCF2xTRkEQxLN0RFmXgyXvyYx1VUjfnK7yQSPmDIscCieGCEoQeryoIsVBdbM1m6x5N8/iY+GQ+oYVkiLs4zUqAZWlI0yxASkzHLaPG+/LBRVrmfgFevOYFL+I39EVZJslxJpLySEkiPhBEGU3kxaBIPFPmTUmq1nbX9njlxY2bZY8sRx+UpXI5IYp5BZsrCkJAG7BQv5dDMCAJXASxDCfSjB/SlwByFmc4hhaVSNDHQk7igjCAJK8HeXxQ7fA40KNaJyb2i7phtcXIOjE0jJ0S2nVB8KGdXsRD3gs1BCVkqqyEWD7C4PCpHIM4QDNAAJe6bzBSQGAEK2YJfGbQKGeitazcljylCHYgqPGC6jM5HTuFc3xJkGSvxLOBiMaxUVbwWizSWU7gcPwiHMNGaSixwjvunudb6Ct4L951004M/s8Nl+plqpz4f6SKOeI6GQnc0stQrOdlTBQA+wUvfblbe0m59z8h7vgpUF4quOZrFoFWVgUWIM+akwJ9pvvgWXDpQnfuPL3sjmsW/vZl+vTL9IXu5gv0C+7oXEGcc+FOCKkE1aY2UbdT+6hDn7vxN1shfPMIfXL7r9K9y7/FOHdpBp8UN/8V4LAsliR36ypg3JPFPVCA+x8B91msZ8j63Cx8YWVndtyyxrPgZHkqdCh+MH4oNFUGJwuTeX5gKpYx7PuDMXgouLRnKXQQmiH7/piZ6uOejeWvP9DZOzq696F9o6P72o6OTWNWZoz+IyHXGw/tHU0m9o9kx/L5sU1kgBDrXP0pHgbKIL1+vf12eSA/WWDuIWSk5fEFJFNbv75mvxWMZhLMPbF8xnilfeA7B9rOYD9WmNw6mc9PfmkyDx5rHxhvH0yY7QNj7VZj7JO5rZO4Rbr/pZLc21SSqlKjX4wsdj7Si20TRzCXBjeHBMf1ZgyeXtmmVTWtXwcnEnX5G76xLWO+b0p1A5wotdul68uD22u17ffuqNV2DNL/uAnh3ooPxFd/hIeMgfdOtZq134lnO2VmT7nTzdZv33d7/XMDRf0XbVfLkgAAAHicY2BkYGAA4vhnBx7H89t8ZeBmvwAUYahR3dAIo/////+ex5T9IpDLwcAEEgUAh08OHwB4nGNgZGBgv8AABDym/////8djysDIgApEAX9SBWwAAHicY2BgYGC/wMDAceT/f25rBgYQZr/w/z+7JgMDWyQQvwXK+TIwcLpD1LHN+/+fx5SBAYQ5LBkYuLIQGCQPwgD/ARBwAAAAAABmAJYAxgD4AYYBnAGyAcAClALqA1oDxAPYA+4EDAVSBcYF9gamBwR4nGNgZGBgEGXUYmBjAAEmIOYCQgaG/2A+AwAPPwFdAHicfZC9bsIwFIVPIFCVqBVSqw6d3KVLRfjZygPAzsAegg2BJE4dg8Te5+gT9Dl4jj5F5x5cL1QqtmR/9zv3JlEAdHFEgNMKcOPO02rgitUvN0n3nkPyk+cWIsSe2/Svnjt4wcRzhDu88QlBeE3ziHfPDdziw3OT/tNzSD56buEBX57b9N+eO5gHXc8RngO1lPXW6qqXpbqsZ3K1yxNz5s6KuTR1pksxjAdnfipLaRIrl2JxEPV+NbJWCWV0ISa6tDLPtaiM3sjUxmtrq3G/r7yPU11gCYkaW1hoVOghQ0oq6WZMVtghRwJzoe//ZM7E8M5cLTDkfx9c6J8yKd1MwlSyU2CBA88ae37LiNZCsVbs0ShIEzd76s65NU3lsg1NSh9j7aYqjNHnVn/6Y/f24geLj26reJxtjUkSgjAUBfMwOIDzdIscKgUfTVUg+JOgeHoL1HJjr7rf5olEvDmK/5yQYAKJFFPMMMcCGXIsscIaG2yxwx4HHHHCWcjCtX1KzI43VbTWF0zUKHqYkP1amqZysqFHSFsdPcnW6n52i9qa0E+Zhsz9VTMpdrEp09Ezb56krOYL5aPWVJpYSx80552zsSY1fGQft+7+nesYaN6xKixpTjoW4gV7uj57) format(\"woff\");font-weight:normal;font-style:normal}.mhp1138_container .mhp1138_icon{font-family:'desktop-icons';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.mhp1138_container .mhp1138_icon-copy:before{content:\"\\E001\"}.mhp1138_container .mhp1138_icon-error:before{content:\"\\E002\"}.mhp1138_container .mhp1138_icon-fullscreen-exit:before{content:\"\\E003\"}.mhp1138_container .mhp1138_icon-fullscreen:before{content:\"\\E004\"}.mhp1138_container .mhp1138_icon-info:before{content:\"\\E005\"}.mhp1138_container .mhp1138_icon-next:before{content:\"\\E006\"}.mhp1138_container .mhp1138_icon-pause:before{content:\"\\E007\"}.mhp1138_container .mhp1138_icon-play:before{content:\"\\E008\"}.mhp1138_container .mhp1138_icon-quality:before{content:\"\\E009\"}.mhp1138_container .mhp1138_icon-replay:before{content:\"\\E00A\"}.mhp1138_container .mhp1138_icon-share-round:before{content:\"\\E00B\"}.mhp1138_container .mhp1138_icon-share:before{content:\"\\E00C\"}.mhp1138_container .mhp1138_icon-size-large:before{content:\"\\E00D\"}.mhp1138_container .mhp1138_icon-size-medium:before{content:\"\\E00E\"}.mhp1138_container .mhp1138_icon-star:before{content:\"\\E00F\"}.mhp1138_container .mhp1138_icon-volume-full:before{content:\"\\E010\"}.mhp1138_container .mhp1138_icon-volume-low:before{content:\"\\E011\"}.mhp1138_container .mhp1138_icon-volume-mute:before{content:\"\\E012\"}.mhp1138_container .mhp1138_icon-vr-clear:before{content:\"\\E013\"}.mhp1138_container .mhp1138_icon-vr:before{content:\"\\E014\"}@font-face{font-family:'grid-icons';src:url(data:application/x-font-ttf;base64,AAEAAAALAIAAAwAwR1NVQiCMJXkAAAE4AAAAVE9TLzJDSUbOAAABjAAAAFZjbWFw4SmjrQAAAewAAAFwZ2x5ZiSFqNIAAANkAAAA8GhlYWRfV62iAAAA4AAAADZoaGVhD78H6AAAALwAAAAkaG10eAfpAAAAAAHkAAAACGxvY2EAeAAAAAADXAAAAAZtYXhwAQ4AVwAAARgAAAAgbmFtZTr1QMsAAARUAAACLnBvc3TXsOvnAAAGhAAAADIAAQAAB9AAAAAAB+kAAP/8B+0AAQAAAAAAAAAAAAAAAAAAAAIAAQAAAAEAAHTjAFVfDzz1AAsH0AAAAAB8JbCBAAAAAHwlsIEAAP//B+0H1AAAAAgAAgAAAAAAAAABAAAAAgBLAAIAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKADAAPgACbGF0bgAOREZMVAAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAED9QGQAAUAAAJ6BXgAAAEYAnoFeAAAA8AAYgIEAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAQOAB4AEH0AAAALQH1AABAAAAAQAAAAAAAAAAAAAH6QAAAAAABQAAAAMAAAAsAAAABAAAAVQAAQAAAAAATgADAAEAAAAsAAMACgAAAVQABAAiAAAABAAEAAEAAOAB//8AAOAB//8AAAABAAQAAAABAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAcAAAAAAAAAAEAAOABAADgAQAAAAEAAAAAAHgAAAACAAD//wftB9QARgBKAAABNiYnNjc2NzYuASczJicmBzY3Njc2NzY9ASYnJicmBwYHBgcGBwYHBg8BBgcRFhcWFxY3MxY3Njc+ATc2JzU+ATc2Jic+AQEhESEH6QEyKjATFQMEIUEqAktYnO0EGCUVJBQZBScyaCMVEwwIDAcaEKKIo1BPFVy65cFVUApQR4ZYLj4FAxI2SgUDFxgmLfgXAX3+gwLZMlQXHCclJy1QOAkQBQkRCitBKkpEVk4Xb0RWDQQPDiIXNiRnP7eanEtJE/yMDxMYCgYBAwQGGQ5JMCclBA1VOSVFGxhPAZ77uAAAABAAxgABAAAAAAABAAoAAAABAAAAAAACAAcACgABAAAAAAADAAoAEQABAAAAAAAEAAoAGwABAAAAAAAFAAsAJQABAAAAAAAGAAoAMAABAAAAAAAKACsAOgABAAAAAAALABMAZQADAAEECQABABQAeAADAAEECQACAA4AjAADAAEECQADABQAmgADAAEECQAEABQArgADAAEECQAFABYAwgADAAEECQAGABQA2AADAAEECQAKAFYA7AADAAEECQALACYBQmdyaWQtaWNvbnNSZWd1bGFyZ3JpZC1pY29uc2dyaWQtaWNvbnNWZXJzaW9uIDEuMGdyaWQtaWNvbnNHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuaHR0cDovL2ZvbnRlbGxvLmNvbQBnAHIAaQBkAC0AaQBjAG8AbgBzAFIAZQBnAHUAbABhAHIAZwByAGkAZAAtAGkAYwBvAG4AcwBnAHIAaQBkAC0AaQBjAG8AbgBzAFYAZQByAHMAaQBvAG4AIAAxAC4AMABnAHIAaQBkAC0AaQBjAG8AbgBzAEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAAcwB2AGcAMgB0AHQAZgAgAGYAcgBvAG0AIABGAG8AbgB0AGUAbABsAG8AIABwAHIAbwBqAGUAYwB0AC4AaAB0AHQAcAA6AC8ALwBmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQAAAAIAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgECAQMACHRodW1iLXVwAAAAAA==) format(\"truetype\"),url(data:application/font-woff;base64,d09GRgABAAAAAASUAAsAAAAABrgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIwleU9TLzIAAAFEAAAAQQAAAFZDSUbOY21hcAAAAYgAAABKAAABcOEpo61nbHlmAAAB1AAAAOgAAADwJIWo0mhlYWQAAAK8AAAAMAAAADZfV62iaGhlYQAAAuwAAAAeAAAAJA+/B+hobXR4AAADDAAAAAgAAAAIB+kAAGxvY2EAAAMUAAAABgAAAAYAeAAAbWF4cAAAAxwAAAAeAAAAIAEOAFduYW1lAAADPAAAATEAAAIuOvVAy3Bvc3QAAARwAAAAIQAAADLXsOvneJxjYGRgYOBiMGCwY2DKSSzJY+BzcfMJYZBiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCAClZBUgAeJxjYGT+yjiBgZWBgamKtYKBgVECQjMfYEhiYgGKMrAyM2AFAWmuKQwODxgfMLJfAHK3sF9hYATSIMwAAMfZCpkAAAB4nO2QsQ2AMBADz8pDgRiBKjWzULG/2CT5GNgils6ST189sAAlOZMA3YiRK63sC5t9UH0Twz9q7e/c4UYrM7v7+JZ/9YI6HJgJVQAAeJxjYGJg+P+f/S37FQY3Bi8GBkYzNXUzcyDUY1Q3VlNXYwdzzM1sGYEcIJcNBvkZ2dgFxcSB0NxYDKjCjtHcTN0URKqp2zEyKgoqsr9kNNIyEBZlZlF01GLyjpjzlkVCVVRFRJJV3ShDWVSYh4OHXUpgUcfiAH/RmF1PD4YGcAW4t0Xo2bEyC5l5sTKLS6jp/hBnrP3XzHTTKERcRl1VXTfAglOAlVOQS9tRy8slzE883yWMl4WfT0ncTCXdfvusOd6ewn96+IUluNgYmVnYJPk8DdRVWXhDLVVdpSX8Gef93gEAODkxAXicY2BkYGAA4pJH31jj+W2+MnCzXwCKMNSobmhE0P//s79lvwLkcjAwgUQBVaUMUHicY2BkYGC/wAAE7C8ZGP7/YX/LwMiACpgAbpoEuwAAAAAAAAfpAAAAAAAAAHgAAHicY2BkYGBgYvAGYgYwi4GBCwgZGP6D+QwAEAEBZgAAeJxtkT1OwzAYht/0D9FKCARiYfECC2r6M3ZkaPcO3dPESVMlceS4Fb0DJ+AQHIKBM3AIDsFb80mVUG3Jfr7H7+coCYBrfCHAcQTo+/U4Wrhg9cdt0o1wh/wg3MUAj8I9+rFwH8+YCQ9wC80bgs4lzR1ehVu4wptwm/5duEP+EO7iHp/CPfpv4T5W+BEe4Cl4yWyeDPPYVM1SZ7sisidxopW2TW4qNQnHJ7nQlbaR04laH1Szz6bOpSq1plRzUzldFEbV1mx17MKNc/VsNErFh7EpkcEiR4Ih1xgGFRos+b4ZdigQ8fRc4pxbsctyz32tMEHI73kuuWCy8ukIjnvC9BoHrg327JjSOqSsU2YMStLc9x7TBaehqf3ZliamD7HxXTX/24gz/ZcP/dPLX2dpY+QAAAB4nGNgYoAAEQbsgImRiZGZgaMkozQ3Sbe0gIEBABnJA1oAAAA=) format(\"woff\");font-weight:normal;font-style:normal}.mhp1138_container .mhp1138_grid-icon{font-family:'grid-icons';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.mhp1138_container .mhp1138_grid-icon-thumb-up:before{content:\"\\E001\"}.mhp1138_container{height:100% !important;width:100% !important;position:relative;background:black;overflow:hidden;font-family:Arial;color:white}.mhp1138_container div,.mhp1138_container span,.mhp1138_container applet,.mhp1138_container object,.mhp1138_container iframe,.mhp1138_container h1,.mhp1138_container h2,.mhp1138_container h3,.mhp1138_container h4,.mhp1138_container h5,.mhp1138_container h6,.mhp1138_container p,.mhp1138_container blockquote,.mhp1138_container pre,.mhp1138_container a,.mhp1138_container abbr,.mhp1138_container acronym,.mhp1138_container address,.mhp1138_container big,.mhp1138_container cite,.mhp1138_container code,.mhp1138_container del,.mhp1138_container dfn,.mhp1138_container em,.mhp1138_container img,.mhp1138_container ins,.mhp1138_container kbd,.mhp1138_container q,.mhp1138_container s,.mhp1138_container samp,.mhp1138_container small,.mhp1138_container strike,.mhp1138_container strong,.mhp1138_container sub,.mhp1138_container sup,.mhp1138_container tt,.mhp1138_container var,.mhp1138_container b,.mhp1138_container u,.mhp1138_container i,.mhp1138_container center,.mhp1138_container dl,.mhp1138_container dt,.mhp1138_container dd,.mhp1138_container ol,.mhp1138_container ul,.mhp1138_container li,.mhp1138_container fieldset,.mhp1138_container form,.mhp1138_container label,.mhp1138_container legend,.mhp1138_container table,.mhp1138_container caption,.mhp1138_container tbody,.mhp1138_container tfoot,.mhp1138_container thead,.mhp1138_container tr,.mhp1138_container th,.mhp1138_container td,.mhp1138_container article,.mhp1138_container aside,.mhp1138_container canvas,.mhp1138_container details,.mhp1138_container embed,.mhp1138_container figure,.mhp1138_container figcaption,.mhp1138_container footer,.mhp1138_container header,.mhp1138_container hgroup,.mhp1138_container menu,.mhp1138_container nav,.mhp1138_container output,.mhp1138_container ruby,.mhp1138_container section,.mhp1138_container summary,.mhp1138_container time,.mhp1138_container mark,.mhp1138_container audio,.mhp1138_container video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}.mhp1138_container article,.mhp1138_container aside,.mhp1138_container details,.mhp1138_container figcaption,.mhp1138_container figure,.mhp1138_container footer,.mhp1138_container header,.mhp1138_container hgroup,.mhp1138_container menu,.mhp1138_container nav,.mhp1138_container section{display:block}.mhp1138_container ol,.mhp1138_container ul{list-style:none}.mhp1138_container blockquote,.mhp1138_container q{quotes:none}.mhp1138_container blockquote:before,.mhp1138_container blockquote:after,.mhp1138_container q:before,.mhp1138_container q:after{content:'';content:none}.mhp1138_container table{border-collapse:collapse;border-spacing:0}.mhp1138_container video{border:none}.mhp1138_container .mhp1138_videoWrapper{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%}.mhp1138_container .mhp1138_videoWrapper video,.mhp1138_container .mhp1138_videoWrapper canvas{position:absolute;top:0;left:0;z-index:0}.mhp1138_container .mhp1138_videoWrapper canvas{height:100%;width:100%}.mhp1138_container button{overflow:visible}.mhp1138_container button::-moz-focus-inner,.mhp1138_container input::-moz-focus-inner{padding:0;border:0}.mhp1138_container *{outline:none}.mhp1138_container .mhp1138_volumeEventCatcher{position:absolute;top:0;left:0;opacity:0.5}.mhp1138_container,.mhp1138_container *{-o-user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}.mhp1138_container *::-moz-selection{background:transparent}.mhp1138_container *::selection{background:transparent}.mhp1138_container .mhp1138_controlBar .mhp1138_grid{float:right;position:relative;height:100%;overflow:hidden;display:none}.mhp1138_container .mhp1138_controlBar .mhp1138_grid .mhp1138_btn{position:relative;font-weight:bold;font-size:14px;line-height:36px}.mhp1138_container.mhp1138_showGrid .mhp1138_playerStateIcon{display:none}.mhp1138_container.mhp1138_showGrid>.mhp1138_share{display:none !important}.mhp1138_container.mhp1138_showGrid .mhp1138_gridMenu{display:block}.mhp1138_container.mhp1138_showGrid .mhp1138_controlBar .mhp1138_grid .mhp1138_btn{color:#ffffff}.mhp1138_container.mhp1138_hideControls .mhp1138_gridMenu .mhp1138_gridContainer{-webkit-transform:translate(0, 22px);-ms-transform:translate(0, 22px);transform:translate(0, 22px)}.mhp1138_gridMenu{position:absolute;top:0;left:0px;width:100%;height:100%;z-index:4;outline:none;background-color:rgba(0,0,0,0.5);display:none}.mhp1138_gridMenu .mhp1138_gridContainer{position:absolute;top:52px;left:0;width:100%;bottom:58px;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;transition:transform .3s ease-in-out, -webkit-transform .3s ease-in-out}.mhp1138_gridMenu .mhp1138_gridContainer .mhp1138_gridWrapper{width:69%}.mhp1138_gridMenu .mhp1138_gridWrapper{position:absolute;left:50%;top:50%;z-index:4;width:66%;-webkit-transform:translate3d(-50%, -50%, 0);transform:translate3d(-50%, -50%, 0);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-touch-callout:none}.mhp1138_gridMenu .mhp1138_prevPage,.mhp1138_gridMenu .mhp1138_nextPage{background-color:#000;padding:17px 4px 17px 5px;width:21px;height:54px;box-sizing:border-box;position:absolute;top:50%;margin:-27px 20px 0;border:0;border-radius:0;cursor:pointer;pointer-events:auto}.mhp1138_gridMenu .mhp1138_prevPage .mhp1138_grid-icon,.mhp1138_gridMenu .mhp1138_nextPage .mhp1138_grid-icon{font-size:20px;line-height:1}.mhp1138_gridMenu .mhp1138_prevPage:hover,.mhp1138_gridMenu .mhp1138_nextPage:hover{background-color:#ccc}.mhp1138_gridMenu .mhp1138_prevPage{right:100%}.mhp1138_gridMenu .mhp1138_nextPage{left:100%}.mhp1138_gridMenu .mhp1138_thumbnailsGrid{box-sizing:border-box;padding:1px;margin:0;text-align:center;line-height:0px}.mhp1138_gridMenu .mhp1138_thumbnailsGrid .mhp1138_gridItem{width:33.333%;padding-bottom:18.3%;height:0;border:2px solid #000;margin:-1px -1px -2px;position:relative;display:inline-block;box-sizing:border-box;background-size:cover;background-color:#000000;background-position:center;background-repeat:no-repeat;pointer-events:auto}.mhp1138_gridMenu .mhp1138_thumbnailsGrid .mhp1138_gridItem:hover .mhp1138_info{opacity:1}.mhp1138_gridMenu .mhp1138_thumbnailsGrid .mhp1138_info{top:-1px;left:-1px;right:-1px;bottom:-1px;position:absolute;background-color:rgba(0,0,0,0.4);font-size:12px;line-height:16px;opacity:0;transition:opacity 0.2s linear;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-touch-callout:none}.mhp1138_gridMenu .mhp1138_thumbnailsGrid .mhp1138_info .mhp1138_title{text-align:left;color:#ff9900;padding:5px;max-height:52px;overflow:hidden}.mhp1138_gridMenu .mhp1138_thumbnailsGrid .mhp1138_info .mhp1138_stats{bottom:0;position:absolute;width:100%;line-height:18px;color:#fff;background:linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 100%);padding:5px;box-sizing:border-box}.mhp1138_gridMenu .mhp1138_thumbnailsGrid .mhp1138_info .mhp1138_stats .mhp1138_time{float:left;font-size:14px}.mhp1138_gridMenu .mhp1138_thumbnailsGrid .mhp1138_info .mhp1138_stats .mhp1138_rating{float:right}.mhp1138_gridMenu .mhp1138_thumbnailsGrid .mhp1138_info .mhp1138_stats .mhp1138_rating .mhp1138_grid-icon{font-size:11px;margin-right:4px;color:#5faa01}.mhp1138_gridMenu .mhp1138_tab{display:inline-block;color:#ccc;text-decoration:none;padding:10px 20px 12px;box-sizing:border-box;cursor:pointer;outline:none}.mhp1138_gridMenu .mhp1138_tab:hover,.mhp1138_gridMenu .mhp1138_tab.mhp1138_active{color:#fff}.mhp1138_container .mhp1138_versionsInfo{position:absolute;z-index:6;top:11%;left:7%;background:rgba(0,0,0,0.75);opacity:0;visibility:hidden;transition:opacity .2s linear;min-width:160px}.mhp1138_container .mhp1138_versionsInfo .mhp1138_copyCloseDiv{border-bottom:1px solid rgba(255,255,255,0.2);overflow:hidden}.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions{width:250px;height:200px;overflow-y:scroll;padding:2px 10px}.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions div div{padding-left:20px;color:#ccc;white-space:nowrap;padding:0px 10px;font-size:12px;text-overflow:ellipsis;overflow:hidden}.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions div div.mhp1138_titleInfo{border-bottom:1px solid rgba(255,255,255,0.2);white-space:nowrap;margin:10px 0;padding:0 5px;font-size:14px;color:#fff}.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions div div.mhp1138_subTitleInfo{margin-top:10px;border-bottom:1px solid rgba(255,255,255,0.2);border-top:1px solid rgba(255,255,255,0.2)}.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.3);border-radius:10px;background-color:rgba(0,0,0,0.75)}.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions::-webkit-scrollbar{width:8px;background-color:rgba(0,0,0,0.75)}.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions::-webkit-scrollbar-thumb{border-radius:10px;-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.3);background-color:#f90}.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions.mhp1138_adaptive .mhp1138_chunkIdDiv,.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions.mhp1138_adaptive .mhp1138_chunkSizeDiv,.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions.mhp1138_adaptive .mhp1138_connectionSpeedDiv{display:block}.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions .mhp1138_chunkIdDiv,.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions .mhp1138_chunkSizeDiv,.mhp1138_container .mhp1138_versionsInfo .mhp1138_playerVersions .mhp1138_connectionSpeedDiv{display:none}.mhp1138_container .mhp1138_versionsInfo .mhp1138_hideVersionMenu,.mhp1138_container .mhp1138_versionsInfo .mhp1138_icon-copy{display:inline;float:right;cursor:pointer;pointer-events:auto;padding:5px}.mhp1138_container .mhp1138_versionsInfo .mhp1138_hideVersionMenu{font-size:25px}.mhp1138_container .mhp1138_versionsInfo .mhp1138_icon-copy{line-height:inherit;color:#999}.mhp1138_container .mhp1138_versionsInfo .mhp1138_icon-copy:active{color:#fff}.mhp1138_container .mhp1138_versionsInfo.mhp1138_active{opacity:1;visibility:visible}.mhp1138_container{font:400 14px/20px \"Helvetica Neue\", Helvetica, Arial, sans-serif;color:#fff;-webkit-font-smoothing:antialiased;background:#000}.mhp1138_container video{background:transparent}.mhp1138_container video::-internal-media-controls-overlay-cast-button{display:none}.mhp1138_container .mhp1138_controlBar{width:100%;height:36px;z-index:6;position:absolute;left:0;bottom:0;right:0px;-webkit-backface-visibility:hidden;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;transition:transform .3s ease-in-out, -webkit-transform .3s ease-in-out}.mhp1138_container .mhp1138_controlBar>.mhp1138_front{position:absolute;top:0;bottom:0;left:0;right:0;padding:0 3px 0 15px;height:36px;z-index:4}.mhp1138_container .mhp1138_controlBar>.mhp1138_background{position:absolute;left:0;right:0;bottom:0;height:64px;background:linear-gradient(to bottom, transparent 0%, rgba(0,0,0,0.48) 39%, rgba(0,0,0,0.65) 95%, rgba(0,0,0,0.71) 100%);z-index:1;opacity:1;transition:opacity 0s ease-in}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen,.mhp1138_container .mhp1138_controlBar .mhp1138_cinema,.mhp1138_container .mhp1138_controlBar .mhp1138_options,.mhp1138_container .mhp1138_controlBar .mhp1138_sound,.mhp1138_container .mhp1138_controlBar .mhp1138_playPause,.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideo,.mhp1138_container .mhp1138_controlBar .mhp1138_volume{height:100%;width:36px;padding:0;margin:0;float:left;position:relative}.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideo{opacity:1;pointer-events:auto;cursor:pointer}.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideoTooltip{position:absolute;bottom:56px;width:390px;height:124px;background:rgba(0,0,0,0.8);padding:8px;left:15px;z-index:6;opacity:1;pointer-events:none;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);transition:opacity .2s linear,-webkit-transform .1s ease-out;transition:opacity .2s linear,transform .1s ease-out;transition:opacity .2s linear,transform .1s ease-out,-webkit-transform .1s ease-out}.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideoTooltip.mhp1138_hidden{opacity:0;-webkit-transform:translate(0, -10px);-ms-transform:translate(0, -10px);transform:translate(0, -10px)}.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideoTooltip .mhp1138_thumb{display:block;height:100%;width:192px;background-size:cover;background-position:center;position:relative;float:left}.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideoTooltip .mhp1138_thumb .mhp1138_duration{position:absolute;bottom:4px;right:6px;line-height:20px;background:rgba(0,0,0,0.7);padding:0px 8px}.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideoTooltip .mhp1138_thumb .mhp1138_duration .mhp1138_hd{font-weight:bold;margin-right:8px}.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideoTooltip .mhp1138_text{width:46%;float:left;padding-left:8px}.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideoTooltip .mhp1138_text .mhp1138_next{font-weight:bold;color:#ccc;padding:5px 0}.mhp1138_container .mhp1138_controlBar .mhp1138_nextVideoTooltip .mhp1138_text .mhp1138_title{color:#f90;max-height:60px;overflow:hidden;text-overflow:ellipsis;display:block;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen,.mhp1138_container .mhp1138_controlBar .mhp1138_cinema,.mhp1138_container .mhp1138_controlBar .mhp1138_chromecast,.mhp1138_container .mhp1138_controlBar .mhp1138_options{float:right}.mhp1138_container .mhp1138_controlBar .mhp1138_playPause>*,.mhp1138_container .mhp1138_controlBar .mhp1138_volume>*,.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen>*,.mhp1138_container .mhp1138_controlBar .mhp1138_cinema>*{transition:opacity .2s linear;opacity:0;pointer-events:none}.mhp1138_container .mhp1138_controlBar .mhp1138_volume>*{padding-bottom:1px;text-align:left;padding-left:8px;transition:none}.mhp1138_container .mhp1138_controlBar .mhp1138_volume>*:before{display:inline-block;overflow:hidden}.mhp1138_container .mhp1138_controlBar .mhp1138_volume.mhp1138_lowVolume .mhp1138_volume-low,.mhp1138_container .mhp1138_controlBar .mhp1138_volume.mhp1138_mediumVolume .mhp1138_volume-low,.mhp1138_container .mhp1138_controlBar .mhp1138_volume.mhp1138_fullVolume .mhp1138_volume-full,.mhp1138_container .mhp1138_controlBar .mhp1138_volume.mhp1138_muteVolume .mhp1138_volume-mute{opacity:1;pointer-events:auto}.mhp1138_container .mhp1138_controlBar .mhp1138_volume.mhp1138_lowVolume .mhp1138_volume-low:before{width:11px;margin-right:10px}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen .mhp1138_icon-fullscreen{opacity:1;pointer-events:auto}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen.mhp1138_fullscreenState .mhp1138_icon-fullscreen-exit{opacity:1;pointer-events:auto}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen.mhp1138_fullscreenState .mhp1138_icon-fullscreen{opacity:0;pointer-events:none}.mhp1138_container .mhp1138_controlBar .mhp1138_chromecast .mhp1138_chromecastBtn{background:transparent;border:0;cursor:pointer;margin:0;padding:5px;width:36px;z-index:5;--disconnected-color:#ccc}.mhp1138_container .mhp1138_controlBar .mhp1138_cinema .mhp1138_icon-size-large{opacity:1;pointer-events:auto}.mhp1138_container .mhp1138_controlBar .mhp1138_cinema.mhp1138_cinemaState .mhp1138_icon-size-medium{opacity:1;pointer-events:auto}.mhp1138_container .mhp1138_controlBar .mhp1138_cinema.mhp1138_cinemaState .mhp1138_icon-size-large{opacity:0;pointer-events:none}.mhp1138_container .mhp1138_controlBar .mhp1138_btn{display:inline-block;background:transparent;margin:0;padding:0 0 2px;border:0;outline:none;z-index:4;font-size:16px;line-height:36px;position:absolute;top:0;left:0;height:100%;cursor:pointer;overflow:visible;text-transform:none;text-align:center;color:#ccc}.mhp1138_container .mhp1138_controlBar .mhp1138_btn:hover,.mhp1138_container .mhp1138_controlBar .mhp1138_btn.mhp1138_hover{color:#fff}.mhp1138_container .mhp1138_controlBar .mhp1138_btn.mhp1138_icon{width:36px;float:none}.mhp1138_container .mhp1138_controlBar .mhp1138_time{height:100%;float:left;display:block;padding:0 16px 0 12px;box-sizing:border-box;text-align:right;line-height:36px}.mhp1138_container .mhp1138_controlBar .mhp1138_time .mhp1138_elapsed{font-weight:700}.mhp1138_container .mhp1138_controlBar .mhp1138_time .mhp1138_sep{padding:0 4px}.mhp1138_container .mhp1138_controlBar .mhp1138_sound{width:auto}.mhp1138_container .mhp1138_controlBar .mhp1138_volumeSlider{float:left;padding:0 8px;width:96px;overflow:hidden}.mhp1138_container .mhp1138_controlBar .mhp1138_volumeSlider.mhp1138_hidden .mhp1138_volumeBar,.mhp1138_container .mhp1138_controlBar .mhp1138_volumeSlider.mhp1138_muted .mhp1138_volumeBar{-webkit-transform:translate(-120%, 0);-ms-transform:translate(-120%, 0);transform:translate(-120%, 0)}.mhp1138_container .mhp1138_controlBar .mhp1138_volumeBar{width:80px;height:36px;position:relative;cursor:pointer;-webkit-backface-visibility:hidden;-webkit-touch-callout:none;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);transition:-webkit-transform .2s ease-out;transition:transform .2s ease-out;transition:transform .2s ease-out, -webkit-transform .2s ease-out}.mhp1138_container .mhp1138_controlBar .mhp1138_volumeBar .mhp1138_front,.mhp1138_container .mhp1138_controlBar .mhp1138_volumeBar .mhp1138_background{position:absolute;top:9px;left:0;z-index:5;width:80px;height:18px;background:#000;background-clip:content-box;box-sizing:border-box;padding:7px 0}.mhp1138_container .mhp1138_controlBar .mhp1138_volumeBar .mhp1138_front{z-index:6;width:50%;background-color:#f90}.mhp1138_container .mhp1138_controlBar .mhp1138_volumeBar .mhp1138_handle{width:5px;height:18px;position:absolute;top:0px;right:-2px;z-index:7;background:#fff}.mhp1138_container .mhp1138_controlBar .mhp1138_volumeBar .mhp1138_extraZone .mhp1138_left{position:absolute;left:-8px;top:0;width:8px;height:36px;cursor:pointer}.mhp1138_container .mhp1138_controlBar .mhp1138_volumeBar .mhp1138_extraZone .mhp1138_right{z-index:9;position:absolute;right:-8px;top:0;width:8px;height:36px;cursor:pointer}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar{position:absolute;height:16px;left:0;right:0;bottom:36px;cursor:pointer;box-sizing:content-box;z-index:3}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar.mhp1138_thumbnailsHoverZone{padding-top:110px}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_background,.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_buffer,.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progress{width:100%;height:6px;position:absolute;bottom:5px;left:0;pointer-events:none}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_hotspots{position:absolute;left:0;bottom:11px;right:0;height:30px;overflow:hidden;z-index:3;display:none;transition:all .25s ease-in-out}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_hotspots svg{display:block;width:100%;height:100%}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_hotspots .mhp1138_hotspotsFill{-webkit-transform:translate3d(-100%, 0px, 0px);transform:translate3d(-100%, 0px, 0px);opacity:0.7}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_background{background:#282828;opacity:0.75;z-index:1}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_buffer{width:auto;z-index:2;background:#6d6d6d}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progressPadding{position:absolute;top:0;bottom:0;left:15px;right:15px;transition:left .3s ease-out,right .3s ease-out}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progressPadding.mhp1138_showHandle .mhp1138_handle{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progressPadding.mhp1138_animated .mhp1138_progress{transition:all .25s ease-in-out}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progressPadding.mhp1138_animated .mhp1138_hotspotsFill{transition:all .25s ease-in-out}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progressPadding .mhp1138_progressOverflow{top:0;left:0;width:100%;height:100%;position:absolute;overflow:hidden}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progress{z-index:3;-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0)}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_handle{position:absolute;bottom:0;width:16px;height:16px;margin-left:-8px;z-index:5;border-radius:8px;background:#fff;cursor:pointer;pointer-events:none;-webkit-backface-visibility:hidden;-webkit-touch-callout:none;-webkit-transform:scale3d(0.001, 0.001, 0.01);transform:scale3d(0.001, 0.001, 0.01);transition:-webkit-transform .25s ease-out;transition:transform .25s ease-out;transition:transform .25s ease-out, -webkit-transform .25s ease-out}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_actionTag{position:absolute;bottom:5px;left:0;min-width:4px;height:6px;margin:auto;opacity:0.5;background-color:#fff;background-clip:content-box;z-index:3;box-sizing:content-box;overflow:hidden}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_actionTag.mhp1138_hover{opacity:0.8}.mhp1138_container .mhp1138_controlBar .mhp1138_options,.mhp1138_container .mhp1138_controlBar .mhp1138_cinema,.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen,.mhp1138_container .mhp1138_controlBar .mhp1138_chromecast,.mhp1138_container .mhp1138_controlBar .mhp1138_logo{margin-right:12px}.mhp1138_container .mhp1138_controlBar .mhp1138_options{margin-right:8px}.mhp1138_container .mhp1138_controlBar .mhp1138_options.mhp1138_menu .mhp1138_btn{color:#fff}.mhp1138_container .mhp1138_controlBar .mhp1138_options.mhp1138_menu .mhp1138_optionsPopup{-webkit-transform:translate(-50%, 0);-ms-transform:translate(-50%, 0);transform:translate(-50%, 0);pointer-events:auto;opacity:1}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_btn.mhp1138_isHD:after{content:'HD';position:absolute;top:5px;right:3px;font:900 7px/1 \"Arial Black\",Arial;display:block;border-radius:2px;padding:2px;background:#f90;color:#000}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup{position:absolute;bottom:32px;margin-left:18px;z-index:6;opacity:0;-webkit-transform:translate(-50%, -10px);-ms-transform:translate(-50%, -10px);transform:translate(-50%, -10px);transition:opacity .2s linear,-webkit-transform .1s ease-out;transition:opacity .2s linear,transform .1s ease-out;transition:opacity .2s linear,transform .1s ease-out,-webkit-transform .1s ease-out;pointer-events:none}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_switchers{padding:5px 0;position:relative;background:rgba(0,0,0,0.75);border-bottom:1px solid rgba(255,255,255,0.2)}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch{position:relative;padding:6px 45px 6px 10px;line-height:15px;cursor:pointer;color:#ccc;cursor:pointer;overflow:hidden;text-align:right;min-width:135px;box-sizing:border-box}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch.mhp1138_hotspots{white-space:nowrap}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch.mhp1138_stateOn span:after{opacity:0}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch.mhp1138_stateOn span:before{opacity:1}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch.mhp1138_stateOn span div{-webkit-transform:translate(10px, 0);-ms-transform:translate(10px, 0);transform:translate(10px, 0)}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch .mhp1138_icon-info{display:inline-block;color:#999;padding-top:18px;margin:-18px 6px 0 0;position:relative;top:1px;font-size:11px;cursor:pointer}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch .mhp1138_icon-info.mhp1138_active,.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch .mhp1138_icon-info:hover{color:#fff}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch span{position:absolute;display:inline-block;background-color:#999;top:6px;right:10px;margin:0;width:25px;height:15px;border-radius:7px;overflow:hidden;transition:background-color .2s linear}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch span:before,.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch span:after{position:absolute;color:#000;top:0;width:18px;text-align:center;font-size:9px;line-height:16px;z-index:2;transition:opacity .2s linear}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch span:before{content:' ';left:0;opacity:0}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch span:after{content:' ';right:0;opacity:1}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch span div{position:absolute;top:2px;left:2px;width:11px;height:11px;background:#fff;z-index:3;border-radius:50%;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);transition:-webkit-transform .2s ease;transition:transform .2s ease;transition:transform .2s ease, -webkit-transform .2s ease}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch:hover,.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch.mhp1138_hover{color:#fff}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch.mhp1138_active{background-color:#f90}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup .mhp1138_optionSwitch.mhp1138_active span{opacity:1}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup ul{margin:0 0 7px;padding:8px 0;background:rgba(0,0,0,0.75)}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup ul:after{content:' ';display:block;position:absolute;top:100%;left:50%;width:0;height:0;padding:0;border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid rgba(0,0,0,0.75);margin:-7px 0 0 -7px}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup ul li{position:relative;margin:0;padding:0 30px;color:#ccc;line-height:24px;text-align:right;white-space:nowrap;cursor:pointer}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup ul li:hover,.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup ul li.mhp1138_hover{color:#fff}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup ul li.mhp1138_active{color:#fff;background:rgba(204,204,204,0.1);cursor:default}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup ul li b{display:inline-block;font-weight:bold;width:20px;text-align:center}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup ul li.mhp1138_upsell span.mhp1138_icon-star{display:block;position:absolute;right:7px;top:6px;width:16px;height:12px;font-size:9px;line-height:11px;text-align:center;border-radius:1px;background:#f90;pointer-events:none;color:#000}.mhp1138_container .mhp1138_controlBar .mhp1138_options .mhp1138_optionsPopup ul li.mhp1138_adaptive b{width:auto}.mhp1138_container .mhp1138_controlBar .mhp1138_logo{width:auto;height:100%;margin:0 16px 0 4px;float:right}.mhp1138_container .mhp1138_controlBar .mhp1138_logo div,.mhp1138_container .mhp1138_controlBar .mhp1138_logo svg{width:auto;height:100%;padding:0;box-sizing:border-box;max-width:60px}.mhp1138_container .mhp1138_controlBar .mhp1138_logo svg.mhp1138_redtube{max-width:70px}.mhp1138_container .mhp1138_controlBar .mhp1138_logo svg.mhp1138_youporn{max-width:90px}.mhp1138_container .mhp1138_controlBar .mhp1138_logo.mhp1138_isLink{cursor:pointer}.mhp1138_container .mhp1138_controlBar .mhp1138_cover{position:absolute;top:0;left:0;right:0;bottom:0;z-index:10;background:transparent;display:none}.mhp1138_container .mhp1138_controlBar .mhp1138_leftVolumeBarCover{position:absolute;top:0;left:0;bottom:0;width:200px;z-index:10;background:transparent;display:none}.mhp1138_container .mhp1138_controlBar .mhp1138_rightVolumeBarCover{position:absolute;display:block;top:0;right:0;bottom:0;left:295px;z-index:10;background:transparent;display:none}.mhp1138_container.mhp1138_readyState .mhp1138_play{opacity:1;pointer-events:auto}.mhp1138_container.mhp1138_replayState .mhp1138_replay{opacity:1;pointer-events:auto}.mhp1138_container.mhp1138_playingState .mhp1138_pause{opacity:1;pointer-events:auto}.mhp1138_container.mhp1138_pausedState .mhp1138_play{opacity:1;pointer-events:auto}.mhp1138_container.mhp1138_seekBarDrag{cursor:pointer}.mhp1138_container.mhp1138_seekBarDrag .mhp1138_controlBar .mhp1138_seekBar .mhp1138_actionTag{padding:1000px 0;margin:-1000px 0}.mhp1138_container.mhp1138_seekBarDrag .mhp1138_controlBar .mhp1138_cover{display:block}.mhp1138_container .mhp1138_eventCatcher{position:absolute;top:0;left:0px;width:100%;height:100%;z-index:4;outline:none}.mhp1138_container .mhp1138_overlayText{position:absolute;font-size:20px;line-height:1.4;width:auto;height:auto;box-sizing:border-box;cursor:default;border-radius:4px;text-shadow:0 0 5px rgba(0,0,0,0.5);color:#fff}.mhp1138_container .mhp1138_overlayText.mhp1138_banner .mhp1138_text{padding:2px}.mhp1138_container .mhp1138_overlayText .mhp1138_text{width:100%;height:100%;padding:2px 10px;border:solid 2px rgba(255,255,255,0.2);border-radius:4px;background-color:none;transition:background-color 0.2s linear, border-color 0.2s linear}.mhp1138_container .mhp1138_overlayText .mhp1138_text img{width:100%;border:0;display:block}.mhp1138_container .mhp1138_overlayText .mhp1138_text iframe{margin:0 -8px;padding:0;border:0;overflow:hidden;display:block}.mhp1138_container .mhp1138_overlayText .mhp1138_text i{font-style:italic}.mhp1138_container .mhp1138_overlayText .mhp1138_text b{font-weight:bold}.mhp1138_container .mhp1138_overlayText .mhp1138_text a{color:#99AAFF}.mhp1138_container .mhp1138_overlayText .mhp1138_text a:hover{color:#CCDDFF}.mhp1138_container .mhp1138_overlayText .mhp1138_text:hover{border-color:rgba(255,255,255,0.5);background-color:rgba(255,255,255,0.1)}.mhp1138_container .mhp1138_overlayText .mhp1138_text:hover .mhp1138_closeButton{opacity:1}.mhp1138_container .mhp1138_overlayText .mhp1138_closeButton{position:absolute;width:18px;height:18px;top:-10px;right:-10px;padding:0;text-align:center;font-weight:bold;padding:0;font-size:20px;line-height:18px;text-shadow:none;box-sizing:border-box;background:#ccc;color:#000;border-radius:50%;cursor:pointer;opacity:0;transition:opacity 0.2s linear}.mhp1138_container .mhp1138_overlayText .mhp1138_closeButton:hover{background:#fff}.mhp1138_container .mhp1138_overlayText.mhp1138_hidden,.mhp1138_container .mhp1138_overlayText.mhp1138_closed{display:none}.mhp1138_container .mhp1138_overlayText.mhp1138_link .mhp1138_text{cursor:pointer}.mhp1138_container .mhp1138_overlayText.mhp1138_hCentered{left:10px;right:10px;text-align:center}.mhp1138_container .mhp1138_overlayText.mhp1138_hCentered .mhp1138_text{position:relative;display:inline-block;width:auto}.mhp1138_container .mhp1138_overlayText.mhp1138_noBorder .mhp1138_text{padding:0;border:none;background-color:none}.mhp1138_container .mhp1138_overlayText.mhp1138_noBorder iframe+.mhp1138_closeButton{right:-18px}.mhp1138_container .mhp1138_playerStateIcon{position:absolute;width:108px;height:108px;top:50%;left:50%;margin:-54px 0 0 -54px;text-align:center;z-index:4;pointer-events:none;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:0;transition:opacity .2s linear}.mhp1138_container .mhp1138_playerStateIcon .mhp1138_play{position:absolute;width:100%;height:100%;display:none;border-radius:54px;overflow:hidden;cursor:pointer;z-index:2;color:#fff}.mhp1138_container .mhp1138_playerStateIcon .mhp1138_play .mhp1138_icon{font-size:36px;line-height:108px;margin-left:11px;border-radius:54px;cursor:pointer}.mhp1138_container .mhp1138_playerStateIcon .mhp1138_buffering{position:absolute;width:100%;height:100%;display:block;z-index:2;-webkit-transform:rotate(32.5deg);-ms-transform:rotate(32.5deg);transform:rotate(32.5deg);display:none}.mhp1138_container .mhp1138_playerStateIcon .mhp1138_background{position:absolute;width:100%;height:100%;overflow:hidden;opacity:0.4;background:#000;border-radius:54px;z-index:1}.mhp1138_container.mhp1138_readyState .mhp1138_playerStateIcon{opacity:1}.mhp1138_container.mhp1138_readyState .mhp1138_playerStateIcon .mhp1138_play{display:block}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.mhp1138_container.mhp1138_bufferingState .mhp1138_playPause .mhp1138_play{opacity:1;pointer-events:auto}.mhp1138_container.mhp1138_bufferingState .mhp1138_playerStateIcon{opacity:1}.mhp1138_container.mhp1138_bufferingState .mhp1138_playerStateIcon .mhp1138_background{display:block}.mhp1138_container.mhp1138_bufferingState .mhp1138_playerStateIcon .mhp1138_play{display:none}.mhp1138_container.mhp1138_bufferingState .mhp1138_playerStateIcon .mhp1138_buffering{display:block}.mhp1138_container.mhp1138_bufferingState .mhp1138_playerStateIcon .mhp1138_buffering svg{display:block;position:relative;margin:14px;width:80px;height:80px;-webkit-animation:spin 0.66s steps(8) infinite;animation:spin 0.66s steps(8) infinite}.mhp1138_container>.mhp1138_share{position:absolute;top:20px;right:28px;width:42px;height:42px;padding:1px;z-index:4;overflow:hidden;cursor:pointer;color:#fff;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);transition:-webkit-transform .3s ease;transition:transform .3s ease;transition:transform .3s ease, -webkit-transform .3s ease}.mhp1138_container>.mhp1138_share .mhp1138_icon{font-size:40px}.mhp1138_container>.mhp1138_share:hover,.mhp1138_container>.mhp1138_share.mhp1138_hover{color:#fff}.mhp1138_container .mhp1138_thumbnails{background:rgba(0,0,0,0.75);position:absolute;bottom:64px;left:50%;z-index:6;padding:3px;pointer-events:none;opacity:1;transition:opacity .2s linear,-webkit-transform .1s ease-out;transition:opacity .2s linear,transform .1s ease-out;transition:opacity .2s linear,transform .1s ease-out,-webkit-transform .1s ease-out}.mhp1138_container .mhp1138_thumbnails.mhp1138_hidden{-webkit-transform:translate(0, -10px);-ms-transform:translate(0, -10px);transform:translate(0, -10px);opacity:0}.mhp1138_container .mhp1138_thumbnails.mhp1138_noImage .mhp1138_box{height:24px}.mhp1138_container .mhp1138_thumbnails.mhp1138_noImage .mhp1138_box .mhp1138_sprite{display:none}.mhp1138_container .mhp1138_thumbnails .mhp1138_actionTagTitle{background:rgba(0,0,0,0.75);position:relative;top:-25px;margin:0 -3px -25px;max-width:166px;line-height:16px;padding:3px 10px;text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:none}.mhp1138_container .mhp1138_thumbnails .mhp1138_arrow{width:0;height:0;margin:0;padding:0;display:block;border-left:10px solid transparent;border-right:10px solid transparent;border-top:10px solid rgba(0,0,0,0.75);position:absolute;top:100%;left:0;z-index:3}.mhp1138_container .mhp1138_thumbnails .mhp1138_box{position:relative;min-width:60px;max-width:160px}.mhp1138_container .mhp1138_thumbnails .mhp1138_box .mhp1138_sprite{max-width:160px;overflow:hidden;position:relative}.mhp1138_container .mhp1138_thumbnails .mhp1138_box .mhp1138_sprite .mhp1138_image,.mhp1138_container .mhp1138_thumbnails .mhp1138_box .mhp1138_sprite .mhp1138_cache{position:absolute;top:0;left:0}.mhp1138_container .mhp1138_thumbnails .mhp1138_box .mhp1138_sprite .mhp1138_cache{visibility:hidden}.mhp1138_container .mhp1138_thumbnails .mhp1138_box .mhp1138_sprite .mhp1138_shadow{position:absolute;bottom:0;left:0;right:0;height:27px;background:linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 100%)}.mhp1138_container .mhp1138_thumbnails .mhp1138_box .mhp1138_selectedTime{position:absolute;bottom:0;left:0;right:0;line-height:24px;text-align:center;z-index:2}.mhp1138_container .mhp1138_tooltip{position:absolute;left:-100px;top:-100px;z-index:6;background:rgba(0,0,0,0.75);padding:4px 15px;cursor:default;pointer-events:none;opacity:1;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);transition:opacity .2s linear,-webkit-transform .1s ease-out;transition:opacity .2s linear,transform .1s ease-out;transition:opacity .2s linear,transform .1s ease-out,-webkit-transform .1s ease-out}.mhp1138_container .mhp1138_tooltip.mhp1138_hidden{-webkit-transform:translate(0, -10px);-ms-transform:translate(0, -10px);transform:translate(0, -10px);opacity:0}.mhp1138_container .mhp1138_tooltip .mhp1138_title{text-align:center;white-space:nowrap}.mhp1138_container .mhp1138_tooltip .mhp1138_arrow{display:block;position:absolute;top:100%;left:0;width:0;height:0;margin:0;padding:0;border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid rgba(0,0,0,0.75);margin-left:-7px}.mhp1138_container .mhp1138_tooltip.mhp1138_topDown.mhp1138_hidden{-webkit-transform:translate(0, 10px);-ms-transform:translate(0, 10px);transform:translate(0, 10px)}.mhp1138_container .mhp1138_tooltip.mhp1138_topDown .mhp1138_arrow{top:auto;bottom:100%;border-top:0;border-bottom:7px solid rgba(0,0,0,0.75)}.mhp1138_container .mhp1138_tooltip.mhp1138_leftSided.mhp1138_hidden{-webkit-transform:translate(-10px, 0);-ms-transform:translate(-10px, 0);transform:translate(-10px, 0)}.mhp1138_container .mhp1138_tooltip.mhp1138_leftSided .mhp1138_arrow{top:50%;bottom:auto;margin-left:0;margin-top:-7px;left:100%;border-top:7px solid transparent;border-bottom:7px solid transparent;border-left:7px solid rgba(0,0,0,0.75)}.mhp1138_container .mhp1138_tooltip.mhp1138_rightSided.mhp1138_hidden{-webkit-transform:translate(10px, 0);-ms-transform:translate(10px, 0);transform:translate(10px, 0)}.mhp1138_container .mhp1138_tooltip.mhp1138_rightSided .mhp1138_arrow{top:50%;bottom:auto;margin-top:-7px;left:0;border-top:7px solid transparent;border-bottom:7px solid transparent;border-right:7px solid rgba(0,0,0,0.75);border-left:0}.mhp1138_container .mhp1138_contextMenu{position:absolute;z-index:6;top:100%;left:100%;background:rgba(0,0,0,0.75);opacity:1;padding:3px 0;transition:opacity .2s linear}.mhp1138_container .mhp1138_contextMenu.mhp1138_hidden{opacity:0;pointer-events:none}.mhp1138_container .mhp1138_contextMenu .mhp1138_content div{color:#ccc;white-space:nowrap;padding:3px 10px;cursor:pointer}.mhp1138_container .mhp1138_contextMenu .mhp1138_content div:hover,.mhp1138_container .mhp1138_contextMenu .mhp1138_content div.mhp1138_hover{color:#fff}.mhp1138_container .mhp1138_contextMenu .mhp1138_content .mhp1138_about{padding-top:5px;margin-top:3px;border-top:1px solid rgba(255,255,255,0.2)}.mhp1138_container .mhp1138_videoErrorMessage{display:none;z-index:4;position:absolute;top:50%;left:50%;white-space:nowrap;margin-top:-12px;float:left;cursor:default}.mhp1138_container .mhp1138_videoErrorMessage .mhp1138_centered{background:#000;margin-left:-50%;float:left;padding:1px 7px;border-radius:3px}.mhp1138_container .mhp1138_videoErrorMessage p{margin:0;padding:2px 0 0 22px;font-size:16px;font-weight:bold;font-family:Arial, Verdana, Serif}.mhp1138_container .mhp1138_videoErrorMessage .mhp1138_icon{float:left;position:relative;top:2px;font-size:16px}.mhp1138_container .mhp1138_preRollTitle{position:relative;z-index:2;background-color:rgba(0,0,0,0.55);border-bottom:1px solid #000000;padding:8px;font-size:14px;font-weight:bold;line-height:14px;display:none}.mhp1138_container .mhp1138_preRollSkipButton{z-index:4;position:absolute;padding:10px;background:rgba(0,0,0,0.55);border:1px solid black;right:0;bottom:75px;cursor:pointer;display:none}.mhp1138_container.mhp1138_preRollRunning .mhp1138_preRollTitle{display:block}.mhp1138_container.mhp1138_preRollRunning .mhp1138_actionTag{display:none !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_progress{background:#690 !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_progress:before{background:#690 !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_handleHover .mhp1138_center{background:#690 !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_chromecast{display:none !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_hotspots{display:none !important}.mhp1138_container.mhp1138_hlsStream .mhp1138_chromecast,.mhp1138_container.mhp1138_dashStream .mhp1138_chromecast{display:none !important}.mhp1138_container .mhp1138_topBar{width:100%;height:46px;position:absolute;top:0;left:0;z-index:5;-webkit-backface-visibility:hidden;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;transition:transform .3s ease-in-out, -webkit-transform .3s ease-in-out}.mhp1138_container .mhp1138_topBar .mhp1138_btn{display:inline-block;background:transparent;margin:0;padding:0 0 0;border:0;outline:none;z-index:4;font-size:24px;line-height:46px;position:absolute;top:0;left:0;height:100%;cursor:pointer;overflow:visible;text-transform:none;text-align:center;color:#ccc}.mhp1138_container .mhp1138_topBar .mhp1138_btn:hover,.mhp1138_container .mhp1138_topBar .mhp1138_btn.mhp1138_hover{color:#fff}.mhp1138_container .mhp1138_topBar .mhp1138_btn.mhp1138_icon{width:36px;float:none}.mhp1138_container .mhp1138_topBar .mhp1138_content{position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}.mhp1138_container .mhp1138_topBar .mhp1138_background{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);opacity:1;z-index:1}.mhp1138_container .mhp1138_topBar .mhp1138_title{height:46px;padding:0 20px}.mhp1138_container .mhp1138_topBar .mhp1138_title span{display:block;width:100%;overflow:hidden;color:#fff;font-size:18px;line-height:46px;white-space:nowrap;text-overflow:ellipsis;cursor:default}.mhp1138_container .mhp1138_topBar .mhp1138_title span.mhp1138_isLink{cursor:pointer}.mhp1138_container .mhp1138_topBar .mhp1138_title span.mhp1138_isLink:hover,.mhp1138_container .mhp1138_topBar .mhp1138_title span.mhp1138_isLink.mhp1138_hover{text-decoration:underline}.mhp1138_container .mhp1138_topBar .mhp1138_share{float:right;width:36px;height:100%;position:relative;z-index:2;margin-right:14px}.mhp1138_container .mhp1138_videoPoster{position:absolute;top:0;left:0;z-index:3;width:100%;height:100%;background-repeat:no-repeat;background-position:center;background-size:cover}.mhp1138_container .mhp1138_staticRoll{position:absolute;z-index:2;top:0;left:0;width:100%;height:100%;cursor:pointer;background-color:#000000;background-repeat:no-repeat;background-position:center;background-size:cover}.mhp1138_container .mhp1138_staticRoll.mhp1138_hidden{display:none}.mhp1138_container .mhp1138_videoWrapper .mhp1138_screenshot{position:absolute;top:0;left:0;width:100%;height:100%;z-index:2;opacity:1;pointer-events:none}.mhp1138_container .mhp1138_videoWrapper .mhp1138_screenshot.mhp1138_hidden{opacity:0}.mhp1138_container .mhp1138_videoWrapper .mhp1138_screenshot canvas{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-transform:translateZ(360deg);transform:translateZ(360deg);-webkit-backface-visibility:hidden;-webkit-touch-callout:none}.mhp1138_container.mhp1138_vr .mhp1138_videoPoster{z-index:2}.mhp1138_container.mhp1138_vr .mhp1138_eventCatcher{display:none}.mhp1138_container.mhp1138_vr .mhp1138_videoWrapper>canvas{position:absolute;top:0;left:0;bottom:0;right:0;z-index:5;-webkit-transform:translateZ(360deg);transform:translateZ(360deg);-webkit-backface-visibility:hidden;backface-visibility:hidden}.mhp1138_container.mhp1138_embedded .mhp1138_controlBar .mhp1138_nextVideo,.mhp1138_container.mhp1138_preRollRunning .mhp1138_controlBar .mhp1138_nextVideo{display:none}.mhp1138_container.mhp1138_embedded .mhp1138_watchHD,.mhp1138_container.mhp1138_preRollRunning .mhp1138_watchHD{position:absolute;z-index:5;top:66px;left:20px;background:rgba(0,0,0,0.9);padding:10px 40px;font-weight:bold;text-transform:uppercase;cursor:pointer;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;transition:transform .3s ease-in-out, -webkit-transform .3s ease-in-out}.mhp1138_container.mhp1138_fullscreenHidden .mhp1138_fullscreen{display:none !important}.mhp1138_container.mhp1138_hideControls{cursor:none !important}.mhp1138_container.mhp1138_hideControls.mhp1138_embedded .mhp1138_watchHD{-webkit-transform:translate(0, -46px);-ms-transform:translate(0, -46px);transform:translate(0, -46px)}.mhp1138_container.mhp1138_hideControls .mhp1138_controlBar{-webkit-transform:translate(0, 45px);-ms-transform:translate(0, 45px);transform:translate(0, 45px)}.mhp1138_container.mhp1138_hideControls .mhp1138_controlBar>.mhp1138_background{opacity:0;transition-duration:.3s}.mhp1138_container.mhp1138_hideControls .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progressPadding{left:0;right:0}.mhp1138_container.mhp1138_hideControls .mhp1138_tooltip,.mhp1138_container.mhp1138_hideControls .mhp1138_thumbnails{display:none !important}.mhp1138_container.mhp1138_hideControls>.mhp1138_share{-webkit-transform:translate(72px, 0);-ms-transform:translate(72px, 0);transform:translate(72px, 0)}.mhp1138_container.mhp1138_hideControls .mhp1138_topBar{-webkit-transform:translate(0, -46px);-ms-transform:translate(0, -46px);transform:translate(0, -46px)}.mhp1138_container.mhp1138_hideControls .mhp1138_eventCatcher{cursor:none !important}.mhp1138_container.mhp1138_hideControls .mhp1138_seekBar .mhp1138_hotspots{opacity:0;pointer-events:none}.mhp1138_container.mhp1138_preRollRunning>.mhp1138_share{display:none !important}";
7/**
8 * @license Satisfy - made to satisfy CSS selectors
9 * Copyright (c) 2009 James Padolsey
10 * -------------------------------------------------------
11 * Dual licensed under the MIT and GPL licenses.
12 * - http://www.opensource.org/licenses/mit-license.php
13 * - http://www.gnu.org/copyleft/gpl.html
14 * -------------------------------------------------------
15 * Version: 0.3
16 * -------------------------------------------------------
17 * (most) Regular Expressions are Copyright (c) John Resig,
18 * from the Sizzle Selector Engine.
19 */
20
21(function (definition) {
22
23 var satisfy = definition();
24 window['satisfy'] = satisfy;
25
26})(function(){
27
28 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
29 exprRegex = {
30 ID: /[^"]#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
31 CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?![^[\]]+])(?:(?!\]))/g,
32 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
33 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/g,
34 TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
35 CLONE: /\:(\d+)(?=$|[:[])/,
36 COMBINATOR: /^[>~+]$/
37 },
38 doc = document,
39 cache = {},
40 attrMap = {
41 'for': 'htmlFor',
42 'class': 'className',
43 'html': 'innerHTML'
44 },
45 callbackTypes = ['ID','CLASS','NAME','ATTR'],
46 exprCallback = {
47 ID: function(match, node) {
48 node.id = selectorPrefix + match[1];
49 },
50 CLASS: function(match, node) {
51 var cls = node.className.replace(/^\s+$/,'');
52 node.className = cls ? cls + ' ' + selectorPrefix + match[1] : selectorPrefix + match[1];
53 },
54 NAME: function(match, node) {
55 node.name = match[1];
56 },
57 ATTR: function(match, node) {
58 var attr = match[1],
59 val = match[4] || true;
60
61 if ( val === true || attr === 'innerHTML' || attrMap.hasOwnProperty(attr) ) {
62 node[attrMap[attr] || attr] = val;
63 } else {
64 node.setAttribute( attr, val );
65 }
66 }
67 },
68 selectorPrefix = '';
69
70 function create(part, n) {
71 var tag = exprRegex.TAG.exec(part),
72 node = doc.createElement( tag && tag[1] !== '*' ? tag[1] : 'div' ),
73 fragment = doc.createDocumentFragment(),
74 c = callbackTypes.length,
75 match, regex, callback;
76
77 while (c--) {
78
79 regex = exprRegex[callbackTypes[c]];
80 callback = exprCallback[callbackTypes[c]];
81
82 if (regex.global) {
83
84 while ( (match = regex.exec(part)) !== null ) {
85 callback( match, node );
86 }
87
88 continue;
89
90 }
91
92 if (match = regex.exec(part)) {
93 callback( match, node );
94 }
95
96 }
97
98 while (n--) {
99 fragment.appendChild( node.cloneNode(true) );
100 }
101
102 return fragment;
103
104 }
105
106 function multiAppend(parents, children) {
107
108 parents = parents.childNodes;
109
110 var i = parents.length,
111 parent;
112
113 while ( i-- ) {
114
115 parent = parents[i];
116
117 if (parent.nodeName.toLowerCase() === 'table') {
118 /* IE requires table to have tbody */
119 parent.appendChild(parent = doc.createElement('tbody'));
120 }
121
122 parent.appendChild(children.cloneNode(true));
123
124 }
125
126 }
127
128 function satisfy(selector, prefix) {
129 if (selector in cache) {
130 return cache[selector].cloneNode(true).childNodes;
131 }
132
133 if( !__.isUndefined(prefix) ){
134 selectorPrefix = prefix;
135 }else{
136 selectorPrefix = '';
137 }
138
139 var selectorParts = [],
140 fragment = doc.createDocumentFragment(),
141 children,
142 prevChildren,
143 curSelector,
144 nClones = 1,
145 nParts = 0,
146 isSibling = false,
147 cloneMatch,
148 m;
149
150 while ( (m = chunker.exec(selector)) !== null ) {
151 ++nParts;
152 selectorParts.push(m[1]);
153 }
154
155 // We're going in reverse
156 while (nParts--) {
157
158 curSelector = selectorParts[nParts];
159
160 if (exprRegex.COMBINATOR.test(curSelector)) {
161 isSibling = curSelector === '~' || curSelector === '+';
162 continue;
163 }
164
165 // Number of clones must be an int >= 1
166 nClones = (cloneMatch = curSelector.match(exprRegex.CLONE)) ? ~~cloneMatch[1] : 1;
167
168 prevChildren = children;
169 children = create(curSelector, nClones);
170
171 if (prevChildren) {
172
173 if (isSibling) {
174 children.appendChild(prevChildren);
175 isSibling = false;
176 } else {
177 multiAppend(children, prevChildren);
178 }
179
180 }
181
182 }
183
184 fragment.appendChild(children);
185
186 cache[selector] = fragment.cloneNode(true);
187
188 return fragment.childNodes;
189
190 }
191
192 satisfy.cache = cache;
193
194 return satisfy;
195});
196function debugInfo(skin, player) {
197 var player = player,
198 skin = skin,
199 version = skin.elements.versionsInfo,
200 versionInfo = __.xest(version.container),
201 hideVersionMenu = __.xest(version.copyCloseDiv.hideVersionMenu),
202 copyBtn = __.xest(version.copyCloseDiv.copyMenu),
203 palyerVersion = __.xest(version.playerVersions.container),
204 playerVersionInfo = __.xest(version.playerVersions.versionInfo),
205 streamingInfo = __.xest(version.playerVersions.streamingInfo),
206 prerollInfo = __.xest(version.playerVersions.prerollInfo),
207 timeRemaining,
208 resetTime,
209 rollActive,
210 forgetUser,
211 timeInterval,
212 lastSegment,
213 currentQuality = player.selectedResolution;
214
215 skin.setTooltipText(copyBtn.firstChild, 'Copy');
216 skin.bindTooltipEvents(copyBtn.firstChild);
217 skin.setTooltipText(hideVersionMenu, 'Close');
218 skin.bindTooltipEvents(hideVersionMenu);
219 createVersionsSubContext();
220 subscribeToPlayerEvents();
221
222 hideVersionMenu.addEventListener('click', function() {
223 hideVersionMenus();
224 });
225
226 copyBtn.addEventListener('click', function() {
227 CopyInfoText();
228 });
229
230
231 function CopyInfoText() {
232 var str = playerVersionInfo.innerText + '\n' + streamingInfo.innerText + '\n' + prerollInfo.innerText;
233
234 if (__.isFunction(skin.copyToClipboard) && !__.isUndefined(str)) {
235 skin.copyToClipboard(str);
236 }
237 }
238
239 function showVersionsMenu() {
240 calculateRemainingTime();
241 __.addClass(versionInfo, 'active');
242
243 }
244
245 function hideVersionMenus() {
246 __.removeClass(versionInfo, 'active');
247 clearInterval(timeInterval);
248 }
249
250 function createVersionsSubContext() {
251 hideVersionMenu.innerHTML = '×';
252 /*------Version------*/
253 createVersionMarkup();
254 setVersionInfo();
255
256
257 /*-------------Adaptive-------------*/
258 createStreamInfoMarkup();
259 updateChunkDetails(currentQuality);
260
261
262 /*------Preroll------*/
263 createRollInfoMarkup();
264 var resetTimeCont;
265
266 if(rollActive) {
267 resetTimeCont = __.xest('.mhp1138_resetTime'); //passing value directly during markup creation doen't display value, as its has : in it hence added after creation
268 resetTimeCont.innerHTML = resetTime;
269 }
270 }
271
272 function createMarkup(infoContainer, data) {
273 var markup;
274 if(data) {
275 markup = __.toMarkup(data, 'mhp1138_');
276 infoContainer.innerHTML = markup;
277 }
278 }
279
280 function createVersionMarkup() {
281 var properties = {
282 '.titleInfo[html="Player Versions"]' : null,
283 '.loaderDiv[html="Loader : "] > span.loader' : null,
284 '.html5Div[html="HTML5 : "] > span.html5player' : null,
285 '.basicDiv[html="Basic : "] > span.basic' : null,
286 '.4playDiv[html="4play : "] > span.4play' : null,
287 '.flashDiv[html="Flash (old) : "] > span.flash' : null
288 };
289
290 createMarkup(playerVersionInfo, properties);
291 }
292
293 function setVersionInfo() {
294 var infoArray = playerVersionInfo.getElementsByTagName('span');
295 MHP1138.appVersions.push({playerName: "Loader", version: MHP1138.loaderVersion});
296
297 __.each(infoArray, function(value, key){
298 var className = value.className.split('_')[1];
299 __.each(MHP1138.appVersions, function(player){
300 var index = (player.playerName.toLowerCase()).indexOf(className);
301 if(index >= 0) {
302 value.innerHTML = player.version;
303 }
304 })
305 });
306 }
307
308 function createStreamInfoMarkup(){
309 var properties = {
310 '.titleInfo[html="Streaming Info"]' : null,
311 '.methodDiv[html="Method : "] > span.streamingMethod' : null,
312 '.qualityDiv[html="Quality : "] > span.streamingQuality' : null,
313 '.subTitleInfo[html="Last Chunk"]' : null,
314 '.chunkIdDiv[html="Chunk ID : "] > span.chunkID' : null,
315 '.chunkSizeDiv[html="Chunk Size : "] > span.chunkSize' : null,
316 '.connectionSpeedDiv[html="Download Time : "] > span.downloadTime' : null,
317 '.connectionSpeedDiv[html="Download Speed : "] > span.downloadSpeed' : null,
318 '.cdnDiv' : 'span[html="CDN : '+ MHP1138.loader.pathToBuildFolder()+'"]'
319 };
320
321 createMarkup(streamingInfo, properties);
322 }
323
324 function updateChunkDetails(quality, format, chunkDetails) {
325 var method = __.xest('.mhp1138_streamingMethod'),
326 chunkID = __.xest('.mhp1138_chunkID'),
327 chunkSize = __.xest('.mhp1138_chunkSize'),
328 qualityVideo = __.xest('.mhp1138_streamingQuality'),
329 connectionSpeed = __.xest('.mhp1138_downloadSpeed'),
330 downloadTime = __.xest('.mhp1138_downloadTime'),
331 isAdaptive = MHP1138.loaderSettings.adaptive;
332
333 if(isAdaptive && !__.isUndefined(chunkDetails)) {
334
335 if(!__.isUndefined(format) && format != '')
336 var qualityString = format == 'hls' ? format.toUpperCase() : __.capitalize(format);
337
338 method.innerHTML = "Adaptive ("+ qualityString +")";
339 chunkID.innerHTML = chunkDetails.hlsChunkId;
340 chunkSize.innerHTML = ((chunkDetails.hlsChunkSize)/1024).toFixed(2)+' KB';
341 connectionSpeed.innerHTML = chunkDetails.hlsChunkBandwidth+ ' Kbps';
342 downloadTime.innerHTML = chunkDetails.hlsChunkDownloadTime+ ' ms';
343 __.addClass(palyerVersion,'adaptive');
344 } else {
345 __.removeClass(palyerVersion,'adaptive');
346 method.innerHTML = 'Progressive';
347 qualityVideo.innerHTML = quality;
348 }
349 }
350
351 function updateQualityDetails(data){
352 var currentQuality = data.height ? data.height : '',
353 qualityVideo = __.xest('.mhp1138_streamingQuality'),
354 quality = player.selectedResolution,
355 adaptiveQuality = (quality == 'hls' || quality == 'dash');
356
357 qualityVideo.innerHTML = adaptiveQuality ? currentQuality + ' (auto)' : quality + ' (forced)';
358 }
359
360 function createRollInfoMarkup() {
361 var active = false,
362 preRollCandidates = [],
363 cookie = store.get('player_preroll') || {},
364 finalData = [],
365 countValue;
366
367 forgetUser = 0;
368 timeRemaining = '00:00',
369
370 __.each(player.campaignCandidates, function(candidate, index) {
371 preRollCandidates[candidate.campaign] = [];
372 preRollCandidates[candidate.campaign].push(candidate);
373 });
374
375 var campaigns = __.keys(preRollCandidates);
376 if(preRollCandidates.length > 0) {
377 active = true;
378 if(__.isEmpty(cookie.time)) {
379 var min;
380 __.each(campaigns, function(campaign, key){
381 __.each(preRollCandidates[campaign], function(value, key){
382 if(value.onNth <= min || __.isUndefined(min)) {
383 min = value.onNth;
384 finalData = value;
385 }
386 });
387 });
388 } else {
389 var minTimeStamp,
390 currentCamp;
391 __.each(cookie.time, function(campaign, key){
392 if(preRollCandidates[key]) {
393 currentCamp = preRollCandidates[key][0];
394 if((currentCamp.forgetUserAfter <= minTimeStamp || __.isUndefined(minTimeStamp))) {
395 minTimeStamp = currentCamp.forgetUserAfter;
396 timeRemaining = campaign;
397 finalData = currentCamp;
398 }
399 }
400 })
401 }
402 }
403
404 forgetUser = finalData.forgetUserAfter;
405 if(player.preRoll.enabled) {
406 cookie.views += 1;
407 }
408 if((cookie.views % finalData.onNth) == 0) {
409 countValue = finalData.onNth;
410 } else {
411 countValue = (cookie.views % finalData.onNth);
412 }
413 resetTime = __.secondToTime(forgetUser);
414 rollActive = active;
415
416 if(active) {
417 var preRollProperties = {
418 '.titleInfo[html="Preroll Info"]' : null,
419 '.activeDiv' : 'span[html="Active : '+active+'"]',
420 '.countDiv' : 'span[html="Count : '+countValue+'"]',
421 '.nthDiv' : 'span[html="Show on : '+finalData.onNth+'"]',
422 '.resetDiv[html="Reset after : "] > span.resetTime' : null,
423 '.timeDiv[html="Time remaining : "] > span.timeRemaining' : null,
424 '.xmlDiv' : 'span[html="XML : '+(finalData.vastParser ? true : false)+'"]'
425 };
426 } else {
427 var preRollProperties = {
428 '.titleInfo[html="Preroll Info"]' : null,
429 '.activeDiv' : 'span[html="Active : '+active+'"]'
430 };
431 }
432
433 createMarkup(prerollInfo, preRollProperties);
434 }
435
436 function calculateRemainingTime() {
437 var futureRoll = new Date((forgetUser*1000)+timeRemaining),
438 currentTimestamp = new Date,
439 timeLeft = 0,
440 liElement = __.xest('.mhp1138_timeRemaining');
441
442 if(futureRoll > currentTimestamp) {
443 var time = futureRoll- currentTimestamp;
444 timeLeft = Math.floor((new Date(time).getTime()) / 1000);
445 }
446
447 if(liElement) {
448 liElement.innerHTML = __.secondToTime(timeLeft);
449
450 timeInterval = setInterval(function(){
451 if(timeLeft >= 0) {
452 liElement.innerHTML = __.secondToTime(timeLeft--);
453 }
454 },1000);
455 }
456 }
457
458 function subscribeToPlayerEvents() {
459 MHP1138.player.subscribeToEvent('fragmentChanged',player.playerId, function(id, event, data) {
460 lastSegment = data.chunkDetails;
461 updateChunkDetails(player.selectedResolution, player.selectedFormat, data.chunkDetails);
462 });
463
464 MHP1138.player.subscribeToEvent('onAdaptiveQualityChange', player.playerId, function(id, event, data) {
465 if(data.quality.mediaType === 'audio') return;
466
467 updateQualityDetails(data.quality);
468 });
469
470 MHP1138.player.subscribeToEvent('onQualityChange',player.playerId, function(id, event, data) {
471 updateChunkDetails(data.resolution, data.format, lastSegment);
472 });
473 }
474
475 return {
476 showVersionsMenu: showVersionsMenu
477 };
478}
479/**
480 * Zest (https://github.com/chjj/zest)
481 * A css selector engine.
482 * Copyright (c) 2011-2012, Christopher Jeffrey. (MIT Licensed)
483 */
484
485// TODO
486// - Recognize the TR subject selector when parsing.
487// - Pass context to scope.
488// - Add :column pseudo-classes.
489
490;(function() {
491
492/**
493 * Shared
494 */
495
496var window = this
497 , document = this.document
498 , old = this.zest;
499
500/**
501 * Helpers
502 */
503
504var compareDocumentPosition = (function() {
505 if (document.compareDocumentPosition) {
506 return function(a, b) {
507 return a.compareDocumentPosition(b);
508 };
509 }
510 return function(a, b) {
511 var el = a.ownerDocument.getElementsByTagName('*')
512 , i = el.length;
513
514 while (i--) {
515 if (el[i] === a) return 2;
516 if (el[i] === b) return 4;
517 }
518
519 return 1;
520 };
521})();
522
523var order = function(a, b) {
524 return compareDocumentPosition(a, b) & 2 ? 1 : -1;
525};
526
527var next = function(el) {
528 while ((el = el.nextSibling)
529 && el.nodeType !== 1);
530 return el;
531};
532
533var prev = function(el) {
534 while ((el = el.previousSibling)
535 && el.nodeType !== 1);
536 return el;
537};
538
539var child = function(el) {
540 if (el = el.firstChild) {
541 while (el.nodeType !== 1
542 && (el = el.nextSibling));
543 }
544 return el;
545};
546
547var lastChild = function(el) {
548 if (el = el.lastChild) {
549 while (el.nodeType !== 1
550 && (el = el.previousSibling));
551 }
552 return el;
553};
554
555var unquote = function(str) {
556 if (!str) return str;
557 var ch = str[0];
558 return ch === '"' || ch === '\''
559 ? str.slice(1, -1)
560 : str;
561};
562
563var indexOf = (function() {
564 if (Array.prototype.indexOf) {
565 return Array.prototype.indexOf;
566 }
567 return function(obj, item) {
568 var i = this.length;
569 while (i--) {
570 if (this[i] === item) return i;
571 }
572 return -1;
573 };
574})();
575
576var makeInside = function(start, end) {
577 var regex = rules.inside.source
578 .replace(/</g, start)
579 .replace(/>/g, end);
580
581 return new RegExp(regex);
582};
583
584var replace = function(regex, name, val) {
585 regex = regex.source;
586 regex = regex.replace(name, val.source || val);
587 return new RegExp(regex);
588};
589
590var truncateUrl = function(url, num) {
591 return url
592 .replace(/^(?:\w+:\/\/|\/+)/, '')
593 .replace(/(?:\/+|\/*#.*?)$/, '')
594 .split('/', num)
595 .join('/');
596};
597
598/**
599 * Handle `nth` Selectors
600 */
601
602var parseNth = function(param, test) {
603 var param = param.replace(/\s+/g, '')
604 , cap;
605
606 if (param === 'even') {
607 param = '2n+0';
608 } else if (param === 'odd') {
609 param = '2n+1';
610 } else if (!~param.indexOf('n')) {
611 param = '0n' + param;
612 }
613
614 cap = /^([+-])?(\d+)?n([+-])?(\d+)?$/.exec(param);
615
616 return {
617 group: cap[1] === '-'
618 ? -(cap[2] || 1)
619 : +(cap[2] || 1),
620 offset: cap[4]
621 ? (cap[3] === '-' ? -cap[4] : +cap[4])
622 : 0
623 };
624};
625
626var nth = function(param, test, last) {
627 var param = parseNth(param)
628 , group = param.group
629 , offset = param.offset
630 , find = !last ? child : lastChild
631 , advance = !last ? next : prev;
632
633 return function(el) {
634 if (el.parentNode.nodeType !== 1) return;
635
636 var rel = find(el.parentNode)
637 , pos = 0;
638
639 while (rel) {
640 if (test(rel, el)) pos++;
641 if (rel === el) {
642 pos -= offset;
643 return group && pos
644 ? !(pos % group) && (pos < 0 === group < 0)
645 : !pos;
646 }
647 rel = advance(rel);
648 }
649 };
650};
651
652/**
653 * Simple Selectors
654 */
655
656var selectors = {
657 '*': (function() {
658 if (function() {
659 var el = document.createElement('div');
660 el.appendChild(document.createComment(''));
661 return !!el.getElementsByTagName('*')[0];
662 }()) {
663 return function(el) {
664 if (el.nodeType === 1) return true;
665 };
666 }
667 return function() {
668 return true;
669 };
670 })(),
671 'type': function(type) {
672 type = type.toLowerCase();
673 return function(el) {
674 return el.nodeName.toLowerCase() === type;
675 };
676 },
677 'attr': function(key, op, val, i) {
678 op = operators[op];
679 return function(el) {
680 var attr;
681 switch (key) {
682 case 'for':
683 attr = el.htmlFor;
684 break;
685 case 'class':
686 // className is '' when non-existent
687 // getAttribute('class') is null
688 attr = el.className;
689 if (attr === '' && el.getAttribute('class') == null) {
690 attr = null;
691 }
692 break;
693 case 'href':
694 attr = el.getAttribute('href', 2);
695 break;
696 case 'title':
697 // getAttribute('title') can be '' when non-existent sometimes?
698 attr = el.getAttribute('title') || null;
699 break;
700 case 'id':
701 if (el.getAttribute) {
702 attr = el.getAttribute('id');
703 break;
704 }
705 default:
706 attr = el[key] != null
707 ? el[key]
708 : el.getAttribute && el.getAttribute(key);
709 break;
710 }
711 if (attr == null) return;
712 attr = attr + '';
713 if (i) {
714 attr = attr.toLowerCase();
715 val = val.toLowerCase();
716 }
717 return op(attr, val);
718 };
719 },
720 ':first-child': function(el) {
721 return !prev(el) && el.parentNode.nodeType === 1;
722 },
723 ':last-child': function(el) {
724 return !next(el) && el.parentNode.nodeType === 1;
725 },
726 ':only-child': function(el) {
727 return !prev(el) && !next(el)
728 && el.parentNode.nodeType === 1;
729 },
730 ':nth-child': function(param, last) {
731 return nth(param, function() {
732 return true;
733 }, last);
734 },
735 ':nth-last-child': function(param) {
736 return selectors[':nth-child'](param, true);
737 },
738 ':root': function(el) {
739 return el.ownerDocument.documentElement === el;
740 },
741 ':empty': function(el) {
742 return !el.firstChild;
743 },
744 ':not': function(sel) {
745 var test = compileGroup(sel);
746 return function(el) {
747 return !test(el);
748 };
749 },
750 ':first-of-type': function(el) {
751 if (el.parentNode.nodeType !== 1) return;
752 var type = el.nodeName;
753 while (el = prev(el)) {
754 if (el.nodeName === type) return;
755 }
756 return true;
757 },
758 ':last-of-type': function(el) {
759 if (el.parentNode.nodeType !== 1) return;
760 var type = el.nodeName;
761 while (el = next(el)) {
762 if (el.nodeName === type) return;
763 }
764 return true;
765 },
766 ':only-of-type': function(el) {
767 return selectors[':first-of-type'](el)
768 && selectors[':last-of-type'](el);
769 },
770 ':nth-of-type': function(param, last) {
771 return nth(param, function(rel, el) {
772 return rel.nodeName === el.nodeName;
773 }, last);
774 },
775 ':nth-last-of-type': function(param) {
776 return selectors[':nth-of-type'](param, true);
777 },
778 ':checked': function(el) {
779 return !!(el.checked || el.selected);
780 },
781 ':indeterminate': function(el) {
782 return !selectors[':checked'](el);
783 },
784 ':enabled': function(el) {
785 return !el.disabled && el.type !== 'hidden';
786 },
787 ':disabled': function(el) {
788 return !!el.disabled;
789 },
790 ':target': function(el) {
791 return el.id === window.location.hash.substring(1);
792 },
793 ':focus': function(el) {
794 return el === el.ownerDocument.activeElement;
795 },
796 ':matches': function(sel) {
797 return compileGroup(sel);
798 },
799 ':nth-match': function(param, last) {
800 var args = param.split(/\s*,\s*/)
801 , arg = args.shift()
802 , test = compileGroup(args.join(','));
803
804 return nth(arg, test, last);
805 },
806 ':nth-last-match': function(param) {
807 return selectors[':nth-match'](param, true);
808 },
809 ':links-here': function(el) {
810 return el + '' === window.location + '';
811 },
812 ':lang': function(param) {
813 return function(el) {
814 while (el) {
815 if (el.lang) return el.lang.indexOf(param) === 0;
816 el = el.parentNode;
817 }
818 };
819 },
820 ':dir': function(param) {
821 return function(el) {
822 while (el) {
823 if (el.dir) return el.dir === param;
824 el = el.parentNode;
825 }
826 };
827 },
828 ':scope': function(el, con) {
829 var context = con || el.ownerDocument;
830 if (context.nodeType === 9) {
831 return el === context.documentElement;
832 }
833 return el === context;
834 },
835 ':any-link': function(el) {
836 return typeof el.href === 'string';
837 },
838 ':local-link': function(el) {
839 if (el.nodeName) {
840 return el.href && el.host === window.location.host;
841 }
842 var param = +el + 1;
843 return function(el) {
844 if (!el.href) return;
845
846 var url = window.location + ''
847 , href = el + '';
848
849 return truncateUrl(url, param) === truncateUrl(href, param);
850 };
851 },
852 ':default': function(el) {
853 return !!el.defaultSelected;
854 },
855 ':valid': function(el) {
856 return el.willValidate || (el.validity && el.validity.valid);
857 },
858 ':invalid': function(el) {
859 return !selectors[':valid'](el);
860 },
861 ':in-range': function(el) {
862 return el.value > el.min && el.value <= el.max;
863 },
864 ':out-of-range': function(el) {
865 return !selectors[':in-range'](el);
866 },
867 ':required': function(el) {
868 return !!el.required;
869 },
870 ':optional': function(el) {
871 return !el.required;
872 },
873 ':read-only': function(el) {
874 if (el.readOnly) return true;
875
876 var attr = el.getAttribute('contenteditable')
877 , prop = el.contentEditable
878 , name = el.nodeName.toLowerCase();
879
880 name = name !== 'input' && name !== 'textarea';
881
882 return (name || el.disabled) && attr == null && prop !== 'true';
883 },
884 ':read-write': function(el) {
885 return !selectors[':read-only'](el);
886 },
887 ':hover': function() {
888 throw new Error(':hover is not supported.');
889 },
890 ':active': function() {
891 throw new Error(':active is not supported.');
892 },
893 ':link': function() {
894 throw new Error(':link is not supported.');
895 },
896 ':visited': function() {
897 throw new Error(':visited is not supported.');
898 },
899 ':column': function() {
900 throw new Error(':column is not supported.');
901 },
902 ':nth-column': function() {
903 throw new Error(':nth-column is not supported.');
904 },
905 ':nth-last-column': function() {
906 throw new Error(':nth-last-column is not supported.');
907 },
908 ':current': function() {
909 throw new Error(':current is not supported.');
910 },
911 ':past': function() {
912 throw new Error(':past is not supported.');
913 },
914 ':future': function() {
915 throw new Error(':future is not supported.');
916 },
917 // Non-standard, for compatibility purposes.
918 ':contains': function(param) {
919 return function(el) {
920 var text = el.innerText || el.textContent || el.value || '';
921 return !!~text.indexOf(param);
922 };
923 },
924 ':has': function(param) {
925 return function(el) {
926 return zest(param, el).length > 0;
927 };
928 }
929 // Potentially add more pseudo selectors for
930 // compatibility with sizzle and most other
931 // selector engines (?).
932};
933
934/**
935 * Attribute Operators
936 */
937
938var operators = {
939 '-': function() {
940 return true;
941 },
942 '=': function(attr, val) {
943 return attr === val;
944 },
945 '*=': function(attr, val) {
946 return attr.indexOf(val) !== -1;
947 },
948 '~=': function(attr, val) {
949 var i = attr.indexOf(val)
950 , f
951 , l;
952
953 if (i === -1) return;
954 f = attr[i - 1];
955 l = attr[i + val.length];
956
957 return (!f || f === ' ') && (!l || l === ' ');
958 },
959 '|=': function(attr, val) {
960 var i = attr.indexOf(val)
961 , l;
962
963 if (i !== 0) return;
964 l = attr[i + val.length];
965
966 return l === '-' || !l;
967 },
968 '^=': function(attr, val) {
969 return attr.indexOf(val) === 0;
970 },
971 '$=': function(attr, val) {
972 return attr.indexOf(val) + val.length === attr.length;
973 },
974 // non-standard
975 '!=': function(attr, val) {
976 return attr !== val;
977 }
978};
979
980/**
981 * Combinator Logic
982 */
983
984var combinators = {
985 ' ': function(test) {
986 return function(el) {
987 while (el = el.parentNode) {
988 if (test(el)) return el;
989 }
990 };
991 },
992 '>': function(test) {
993 return function(el) {
994 return test(el = el.parentNode) && el;
995 };
996 },
997 '+': function(test) {
998 return function(el) {
999 return test(el = prev(el)) && el;
1000 };
1001 },
1002 '~': function(test) {
1003 return function(el) {
1004 while (el = prev(el)) {
1005 if (test(el)) return el;
1006 }
1007 };
1008 },
1009 'noop': function(test) {
1010 return function(el) {
1011 return test(el) && el;
1012 };
1013 },
1014 'ref': function(test, name) {
1015 var node;
1016
1017 function ref(el) {
1018 var doc = el.ownerDocument
1019 , nodes = doc.getElementsByTagName('*')
1020 , i = nodes.length;
1021
1022 while (i--) {
1023 node = nodes[i];
1024 if (ref.test(el)) {
1025 node = null;
1026 return true;
1027 }
1028 }
1029
1030 node = null;
1031 }
1032
1033 ref.combinator = function(el) {
1034 if (!node || !node.getAttribute) return;
1035
1036 var attr = node.getAttribute(name) || '';
1037 if (attr[0] === '#') attr = attr.substring(1);
1038
1039 if (attr === el.id && test(node)) {
1040 return node;
1041 }
1042 };
1043
1044 return ref;
1045 }
1046};
1047
1048/**
1049 * Grammar
1050 */
1051
1052var rules = {
1053 qname: /^ *([\w\-]+|\*)/,
1054 simple: /^(?:([.#][\w\-]+)|pseudo|attr)/,
1055 ref: /^ *\/([\w\-]+)\/ */,
1056 combinator: /^(?: +([^ \w*]) +|( )+|([^ \w*]))(?! *$)/,
1057 attr: /^\[([\w\-]+)(?:([^\w]?=)(inside))?\]/,
1058 pseudo: /^(:[\w\-]+)(?:\((inside)\))?/,
1059 inside: /(?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|<[^"'>]*>|\\["'>]|[^"'>])*/
1060};
1061
1062rules.inside = replace(rules.inside, '[^"\'>]*', rules.inside);
1063rules.attr = replace(rules.attr, 'inside', makeInside('\\[', '\\]'));
1064rules.pseudo = replace(rules.pseudo, 'inside', makeInside('\\(', '\\)'));
1065rules.simple = replace(rules.simple, 'pseudo', rules.pseudo);
1066rules.simple = replace(rules.simple, 'attr', rules.attr);
1067
1068/**
1069 * Compiling
1070 */
1071
1072var compile = function(sel) {
1073 var sel = sel.replace(/^\s+|\s+$/g, '')
1074 , test
1075 , filter = []
1076 , buff = []
1077 , subject
1078 , qname
1079 , cap
1080 , op
1081 , ref;
1082
1083 while (sel) {
1084 if (cap = rules.qname.exec(sel)) {
1085 sel = sel.substring(cap[0].length);
1086 qname = cap[1];
1087 buff.push(tok(qname, true));
1088 } else if (cap = rules.simple.exec(sel)) {
1089 sel = sel.substring(cap[0].length);
1090 qname = '*';
1091 buff.push(tok(qname, true));
1092 buff.push(tok(cap));
1093 } else {
1094 throw new Error('Invalid selector.');
1095 }
1096
1097 while (cap = rules.simple.exec(sel)) {
1098 sel = sel.substring(cap[0].length);
1099 buff.push(tok(cap));
1100 }
1101
1102 if (sel[0] === '!') {
1103 sel = sel.substring(1);
1104 subject = makeSubject();
1105 subject.qname = qname;
1106 buff.push(subject.simple);
1107 }
1108
1109 if (cap = rules.ref.exec(sel)) {
1110 sel = sel.substring(cap[0].length);
1111 ref = combinators.ref(makeSimple(buff), cap[1]);
1112 filter.push(ref.combinator);
1113 buff = [];
1114 continue;
1115 }
1116
1117 if (cap = rules.combinator.exec(sel)) {
1118 sel = sel.substring(cap[0].length);
1119 op = cap[1] || cap[2] || cap[3];
1120 if (op === ',') {
1121 filter.push(combinators.noop(makeSimple(buff)));
1122 break;
1123 }
1124 } else {
1125 op = 'noop';
1126 }
1127
1128 filter.push(combinators[op](makeSimple(buff)));
1129 buff = [];
1130 }
1131
1132 test = makeTest(filter);
1133 test.qname = qname;
1134 test.sel = sel;
1135
1136 if (subject) {
1137 subject.lname = test.qname;
1138
1139 subject.test = test;
1140 subject.qname = subject.qname;
1141 subject.sel = test.sel;
1142 test = subject;
1143 }
1144
1145 if (ref) {
1146 ref.test = test;
1147 ref.qname = test.qname;
1148 ref.sel = test.sel;
1149 test = ref;
1150 }
1151
1152 return test;
1153};
1154
1155var tok = function(cap, qname) {
1156 // qname
1157 if (qname) {
1158 return cap === '*'
1159 ? selectors['*']
1160 : selectors.type(cap);
1161 }
1162
1163 // class/id
1164 if (cap[1]) {
1165 return cap[1][0] === '.'
1166 ? selectors.attr('class', '~=', cap[1].substring(1))
1167 : selectors.attr('id', '=', cap[1].substring(1));
1168 }
1169
1170 // pseudo-name
1171 // inside-pseudo
1172 if (cap[2]) {
1173 return cap[3]
1174 ? selectors[cap[2]](unquote(cap[3]))
1175 : selectors[cap[2]];
1176 }
1177
1178 // attr name
1179 // attr op
1180 // attr value
1181 if (cap[4]) {
1182 var i;
1183 if (cap[6]) {
1184 i = cap[6].length;
1185 cap[6] = cap[6].replace(/ +i$/, '');
1186 i = i > cap[6].length;
1187 }
1188 return selectors.attr(cap[4], cap[5] || '-', unquote(cap[6]), i);
1189 }
1190
1191 throw new Error('Unknown Selector.');
1192};
1193
1194var makeSimple = function(func) {
1195 var l = func.length
1196 , i;
1197
1198 // Potentially make sure
1199 // `el` is truthy.
1200 if (l < 2) return func[0];
1201
1202 return function(el) {
1203 if (!el) return;
1204 for (i = 0; i < l; i++) {
1205 if (!func[i](el)) return;
1206 }
1207 return true;
1208 };
1209};
1210
1211var makeTest = function(func) {
1212 if (func.length < 2) {
1213 return function(el) {
1214 return !!func[0](el);
1215 };
1216 }
1217 return function(el) {
1218 var i = func.length;
1219 while (i--) {
1220 if (!(el = func[i](el))) return;
1221 }
1222 return true;
1223 };
1224};
1225
1226var makeSubject = function() {
1227 var target;
1228
1229 function subject(el) {
1230 var node = el.ownerDocument
1231 , scope = node.getElementsByTagName(subject.lname)
1232 , i = scope.length;
1233
1234 while (i--) {
1235 if (subject.test(scope[i]) && target === el) {
1236 target = null;
1237 return true;
1238 }
1239 }
1240
1241 target = null;
1242 }
1243
1244 subject.simple = function(el) {
1245 target = el;
1246 return true;
1247 };
1248
1249 return subject;
1250};
1251
1252var compileGroup = function(sel) {
1253 var test = compile(sel)
1254 , tests = [ test ];
1255
1256 while (test.sel) {
1257 test = compile(test.sel);
1258 tests.push(test);
1259 }
1260
1261 if (tests.length < 2) return test;
1262
1263 return function(el) {
1264 var l = tests.length
1265 , i = 0;
1266
1267 for (; i < l; i++) {
1268 if (tests[i](el)) return true;
1269 }
1270 };
1271};
1272
1273/**
1274 * Selection
1275 */
1276
1277var find = function(sel, node) {
1278 var results = []
1279 , test = compile(sel)
1280 , scope = node.getElementsByTagName(test.qname)
1281 , i = 0
1282 , el;
1283
1284 while (el = scope[i++]) {
1285 if (test(el)) results.push(el);
1286 }
1287
1288 if (test.sel) {
1289 while (test.sel) {
1290 test = compile(test.sel);
1291 scope = node.getElementsByTagName(test.qname);
1292 i = 0;
1293 while (el = scope[i++]) {
1294 if (test(el) && !~indexOf.call(results, el)) {
1295 results.push(el);
1296 }
1297 }
1298 }
1299 results.sort(order);
1300 }
1301
1302 return results;
1303};
1304
1305/**
1306 * Native
1307 */
1308
1309var select = (function() {
1310 var slice = (function() {
1311 try {
1312 Array.prototype.slice.call(document.getElementsByTagName('zest'));
1313 return Array.prototype.slice;
1314 } catch(e) {
1315 e = null;
1316 return function() {
1317 var a = [], i = 0, l = this.length;
1318 for (; i < l; i++) a.push(this[i]);
1319 return a;
1320 };
1321 }
1322 })();
1323
1324 if (document.querySelectorAll) {
1325 return function(sel, node) {
1326 try {
1327 return slice.call(node.querySelectorAll(sel));
1328 } catch(e) {
1329 return find(sel, node);
1330 }
1331 };
1332 }
1333
1334 return function(sel, node) {
1335 try {
1336 if (sel[0] === '#' && /^#[\w\-]+$/.test(sel)) {
1337 return [node.getElementById(sel.substring(1))];
1338 }
1339 if (sel[0] === '.' && /^\.[\w\-]+$/.test(sel)) {
1340 sel = node.getElementsByClassName(sel.substring(1));
1341 return slice.call(sel);
1342 }
1343 if (/^[\w\-]+$/.test(sel)) {
1344 return slice.call(node.getElementsByTagName(sel));
1345 }
1346 } catch(e) {
1347 ;
1348 }
1349 return find(sel, node);
1350 };
1351})();
1352
1353/**
1354 * Zest
1355 */
1356
1357var zest = function(sel, node) {
1358 try {
1359 sel = select(sel, node || document);
1360 } catch(e) {
1361 if (window.ZEST_DEBUG) {
1362 console.log(e.stack || e + '');
1363 }
1364 sel = [];
1365 }
1366 return sel;
1367};
1368
1369/**
1370 * Expose
1371 */
1372
1373zest.selectors = selectors;
1374zest.operators = operators;
1375zest.combinators = combinators;
1376zest.compile = compileGroup;
1377
1378zest.matches = function(el, sel) {
1379 return !!compileGroup(sel)(el);
1380};
1381
1382zest.cache = function() {
1383 if (compile.raw) return;
1384
1385 var raw = compile
1386 , cache = {};
1387
1388 compile = function(sel) {
1389 return cache[sel]
1390 || (cache[sel] = raw(sel));
1391 };
1392
1393 compile.raw = raw;
1394 zest._cache = cache;
1395};
1396
1397zest.noCache = function() {
1398 if (!compile.raw) return;
1399 compile = compile.raw;
1400 delete zest._cache;
1401};
1402
1403zest.noConflict = function() {
1404 window.zest = old;
1405 return zest;
1406};
1407
1408zest.noNative = function() {
1409 select = find;
1410};
1411
1412if (typeof module !== 'undefined') {
1413 module.exports = zest;
1414} else {
1415 this.zest = zest;
1416}
1417
1418if (window.ZEST_DEBUG) {
1419 zest.noNative();
1420} else {
1421 zest.cache();
1422}
1423
1424}).call(function() {
1425 return this || (typeof window !== 'undefined' ? window : global);
1426}());
1427
1428(function(window) {
1429 'use strict';
1430
1431 var Locales = {
1432 en: {
1433 '%PLAY%': 'Play',
1434 '%PAUSE%': 'Pause',
1435 '%REPLAY%': 'Replay',
1436 '%NEXT%': 'Next',
1437 '%MUTE%': 'Mute',
1438 '%UNMUTE%': 'Unmute',
1439 '%FULL_SCREEN%': 'Full screen',
1440 '%EXIT_FULL_SCREEN%': 'Exit full screen',
1441 '%CHROMECAST%': 'Stream on TV',
1442 '%EXIT_CHROMECAST%': 'Disable streaming',
1443 '%LARGE_PLAYER%': 'Large Player',
1444 '%SMALL_PLAYER%': 'Small Player',
1445 '%QUALITY%': 'Quality',
1446 '%AUTO_QUALITY%': 'Auto',
1447 '%ADVERTISEMENT_TITLE%': 'Advertisement: Your video will resume shortly',
1448 '%SKIP_AD%': 'Skip Ad >>',
1449 '%SKIP_TIMER%': 'You can skip this video in % second(s)',
1450 '%SHARE%': 'Share',
1451 '%COPY_EMBED_CODE%': 'Copy Embed Code',
1452 '%COPY_URL_CURRENT_TIME%': 'Copy Video URL From Current Time',
1453 '%COPY_URL%': 'Copy Video URL',
1454 '%ABOUT%': 'Debug Info',
1455 '%AUTOPLAY%': 'Autoplay',
1456 '%HOTSPOTS%': 'Hotspots',
1457 '%SLOWMOTION%': 'Slow Motion',
1458 '%HOTSPOTS_HOT_NOT%': "See what’s hot and what’s not",
1459 '%NOT_AVAILABLE%': 'Video is not available at the moment.',
1460 '%ERROR_OCCURED%': 'An error occured, please try again later or <a href="javascript:window.location.reload()">reload</a> the page.',
1461 '%WATCH_HD%': 'Watch in HD'
1462 },
1463 ru: {
1464 '%PLAY%': 'ÒþÑÂÿрþø÷òõÑÂтø',
1465 '%PAUSE%': 'ßðу÷ð',
1466 '%REPLAY%': 'ßþòтþр',
1467 '%NEXT%': 'áûõôующøù',
1468 '%MUTE%': 'Þтúûючøть ÷òуú',
1469 '%UNMUTE%': 'Òúûючøть ÷òуú',
1470 '%FULL_SCREEN%': 'ßþûýыù ÑÂúрðý',
1471 '%EXIT_FULL_SCREEN%': 'Ã’ыхþô ø÷ ÿþûýþóþ ÑÂúрðýð',
1472 '%CHROMECAST%': 'âрðýÑÂûøрþòðть ýð âÒ',
1473 '%EXIT_CHROMECAST%': 'ßрõúрðтøть трðýÑÂÃȄÂцøю',
1474 '%LARGE_PLAYER%': 'ãòõûøчøть',
1475 '%SMALL_PLAYER%': 'ãüõýьшøть',
1476 '%QUALITY%': 'ÚðчõÑÂтòþ',
1477 '%AUTO_QUALITY%': 'ÃÂòтþ',
1478 '%ADVERTISEMENT_TITLE%': 'à õúûðüð: Òðшõ òøôõþ ÿрþôþûöøтÑÂÑ ÑÂþòÑÂõü ÑÂúþрþ',
1479 '%SKIP_AD%': 'ßрþÿуÑÂтøть рõúûðüу >>',
1480 '%SKIP_TIMER%': 'Ã’Ñ‹ üþöõтõ ÿрþÿуÑÂтøть ÑÂтþ òøôõþ чõрõ÷ % ÑÂõúуýô',
1481 '%SHARE%': 'ßþôõûøтьÑÂÑÂ',
1482 '%COPY_EMBED_CODE%': 'Úþÿøрþòðть HTML-úþô',
1483 '%COPY_URL_CURRENT_TIME%': 'Úþÿøрþòðть URL òøôõþ ѠÿрøòÑÂ÷úþù úþ òрõüõýø',
1484 '%COPY_URL%': 'Úþÿøрþòðть URL òøôõþ',
1485 '%ABOUT%': 'ØýфþрüðцøѠþñ þтûðôúõ',
1486 '%AUTOPLAY%': 'ÃÂòтþòþÑÂÿр.',
1487 '%HOTSPOTS%': 'ÓþрÑÂчõõ',
1488 '%SLOWMOTION%': '×ðüõôûõýýðѠÑÂъõüúð',
1489 '%HOTSPOTS_HOT_NOT%': "ã÷ýðù, чтþ ÑÂтþøт ÑÂüþтрõть",
1490 '%NOT_AVAILABLE%': 'Òøôõþ ýõôþÑÂтуÿýþ ò ôðýýыù üþüõýт.',
1491 '%ERROR_OCCURED%': 'ßрþø÷þшûð þшøñúð. ßþöðûуùÑÂтð, ÿþÿрþñуùтõ ÿþ÷öõ øûø <a href="javascript:window.location.reload()">ÿõрõ÷ðóру÷øтõ</a> ÑÂтрðýøцу.'
1492 },
1493 fr: {
1494 '%PLAY%': 'Lecture',
1495 '%PAUSE%': 'Pause',
1496 '%REPLAY%': 'Rejouer',
1497 '%NEXT%': 'Suivant',
1498 '%MUTE%': 'Muet',
1499 '%UNMUTE%': 'Non muet',
1500 '%FULL_SCREEN%': 'Écran complet',
1501 '%EXIT_FULL_SCREEN%': "Sortir de l’écran complet",
1502 '%CHROMECAST%': 'Stream à la télé',
1503 '%EXIT_CHROMECAST%': 'Désactiver le streaming',
1504 '%LARGE_PLAYER%': 'Lecteur large',
1505 '%SMALL_PLAYER%': 'Petit lecteur',
1506 '%QUALITY%': 'Qualité',
1507 '%AUTO_QUALITY%': 'Auto',
1508 '%ADVERTISEMENT_TITLE%': 'Publicité: votre vidéo reprendra sous peu',
1509 '%SKIP_AD%': 'Ignorer la publicité >>',
1510 '%SKIP_TIMER%': 'Vous pouvez ignorer cette vidéo dans % secondes',
1511 '%SHARE%': 'Partager',
1512 '%COPY_EMBED_CODE%': "Copier le code d’intégration",
1513 '%COPY_URL_CURRENT_TIME%': 'Copier le lien URL de la vidéo à partir heure actuelle',
1514 '%COPY_URL%': "Copier l’URL de la vidéo",
1515 '%ABOUT%': 'Les informations de débogage',
1516 '%AUTOPLAY%': 'Lecture auto',
1517 '%HOTSPOTS%': 'Hotspots',
1518 '%SLOWMOTION%': 'Ralenti',
1519 '%HOTSPOTS_HOT_NOT%': "Voyez ce qui est chaud et ce qui ne l’est pas",
1520 '%NOT_AVAILABLE%': "La vidéo n'est pas disponible pour le moment.",
1521 '%ERROR_OCCURED%': 'Une erreur est survenue, réessayez ultérieurement ou <a href="javascript:window.location.reload()">rechargez</a> la page.'
1522 },
1523 tk: {
1524 '%PLAY%': 'Oynat',
1525 '%PAUSE%': 'Durdur',
1526 '%REPLAY%': 'Tekrar',
1527 '%NEXT%': 'Sonraki',
1528 '%MUTE%': 'Sessiz',
1529 '%UNMUTE%': 'Sesi aç',
1530 '%FULL_SCREEN%': 'Tam Ekran',
1531 '%EXIT_FULL_SCREEN%': 'Tam Ekrandan Çık',
1532 '%CHROMECAST%': "TV’de akış yapın",
1533 '%EXIT_CHROMECAST%': 'Akışı devre dışı bırak',
1534 '%LARGE_PLAYER%': 'GeniÅŸ Ekran',
1535 '%SMALL_PLAYER%': 'Küçük Ekran',
1536 '%QUALITY%': 'Kalite',
1537 '%AUTO_QUALITY%': 'Otomatik',
1538 '%ADVERTISEMENT_TITLE%': 'Reklam: Videonuz kısa bir süre sonra devam edecektir',
1539 '%SKIP_AD%': 'Reklamları Geç >>',
1540 '%SKIP_TIMER%': 'Bu videoyu % saniye sonra atlayabilirsiniz',
1541 '%SHARE%': 'PaylaÅŸ',
1542 '%COPY_EMBED_CODE%': 'Gömülü Kodu Kopyala',
1543 '%COPY_URL_CURRENT_TIME%': "Geçerli Saatteki Video URL’sini Kopyala",
1544 '%COPY_URL%': "Video URL’sini Kopyala",
1545 '%ABOUT%': 'Bilgiyi Denetle',
1546 '%AUTOPLAY%': 'Otomatik Oynat',
1547 '%HOTSPOTS%': 'Popüler Noktalar',
1548 '%SLOWMOTION%': 'Ağır çekim',
1549 '%HOTSPOTS_HOT_NOT%': 'Popüler olanlar ve olmayanlar',
1550 '%NOT_AVAILABLE%': 'Video şu an oynatılamıyor.',
1551 '%ERROR_OCCURED%': 'Bir hata oluştu, lütfen sonra tekrar deneyiniz ya da <a href="javascript:window.location.reload()">yeniden yükleyiniz</a> yeniden yükleyiniz.'
1552 },
1553 pt: {
1554 '%PLAY%': 'Reproduzir',
1555 '%PAUSE%': 'Pausar',
1556 '%REPLAY%': 'Repetição',
1557 '%NEXT%': 'Próximo',
1558 '%MUTE%': 'Mudo',
1559 '%UNMUTE%': 'Tirar do mudo',
1560 '%FULL_SCREEN%': 'Tela cheia',
1561 '%EXIT_FULL_SCREEN%': 'Sair da Tela Cheia',
1562 '%CHROMECAST%': 'Stream na TV',
1563 '%EXIT_CHROMECAST%': 'Desativar transmissão',
1564 '%LARGE_PLAYER%': 'Jogador Grande',
1565 '%SMALL_PLAYER%': 'Jogador Pequeno',
1566 '%QUALITY%': 'Qualidade',
1567 '%AUTO_QUALITY%': 'Auto',
1568 '%ADVERTISEMENT_TITLE%': 'Anúncio: seu vÃÂdeo será retomado em breve',
1569 '%SKIP_AD%': 'Pular Anúncio >>',
1570 '%SKIP_TIMER%': 'Pode ignorar este vÃÂdeo em % segundos',
1571 '%SHARE%': 'Compartilhar',
1572 '%COPY_EMBED_CODE%': 'Copiar o Código Embutido',
1573 '%COPY_URL_CURRENT_TIME%': 'Copiar URL do VÃÂdeo a Partir do Tempo Atual',
1574 '%COPY_URL%': 'Copiar URL do VÃÂdeo',
1575 '%ABOUT%': 'Informação de depuração',
1576 '%AUTOPLAY%': 'Reprodução Automática',
1577 '%HOTSPOTS%': 'Ponto de Acesso',
1578 '%SLOWMOTION%': 'Câmera lenta',
1579 '%HOTSPOTS_HOT_NOT%': 'Veja o que é tendência e o que não é',
1580 '%NOT_AVAILABLE%': 'O vÃÂdeo não está disponÃÂvel no momento.',
1581 '%ERROR_OCCURED%': 'Ocorreu um erro, tente novamente mais tarde ou <a href="javascript:window.location.reload()">recarregue</a> a página.'
1582 },
1583 pl: {
1584 '%PLAY%': 'Odtwórz',
1585 '%PAUSE%': 'Pauza',
1586 '%REPLAY%': 'Powtórna rozgrywka',
1587 '%NEXT%': 'Następny',
1588 '%MUTE%': 'Wycisz',
1589 '%UNMUTE%': 'Włącz głos',
1590 '%FULL_SCREEN%': 'Pełen ekran',
1591 '%EXIT_FULL_SCREEN%': 'Wyłącz pełen ekran',
1592 '%CHROMECAST%': 'Strumień w telewizji',
1593 '%EXIT_CHROMECAST%': 'Wyłącz strumieniowanie',
1594 '%LARGE_PLAYER%': 'Duzy odtwarzacz',
1595 '%SMALL_PLAYER%': 'Mały odtwarzacz',
1596 '%QUALITY%': 'Jakość',
1597 '%AUTO_QUALITY%': 'Auto',
1598 '%ADVERTISEMENT_TITLE%': 'Reklama: Twoj film wkrótce zostanie wyświetlony',
1599 '%SKIP_AD%': 'Pomiń Reklamę >>',
1600 '%SKIP_TIMER%': 'Mozesz wyłączyć ten filmik za % sekund',
1601 '%SHARE%': 'Uwspólnij',
1602 '%COPY_EMBED_CODE%': 'Skopiuj Adres Odnośnika',
1603 '%COPY_URL_CURRENT_TIME%': 'Skopiuj Adres URL Filmu Od BiezÄ…cego Momentu',
1604 '%COPY_URL%': 'Skopiuj Adres URL Filmu',
1605 '%ABOUT%': 'Informacje debugowania',
1606 '%AUTOPLAY%': 'autoodtwarzanie',
1607 '%HOTSPOTS%': 'Hotspoty',
1608 '%SLOWMOTION%': 'Zwolnione tempo',
1609 '%HOTSPOTS_HOT_NOT%': 'Co jest hot, a co nie',
1610 '%NOT_AVAILABLE%': 'Film nie jest teraz dostępny.',
1611 '%ERROR_OCCURED%': 'Wystąpił błąd, spróbuj ponownie później lub <a href="javascript:window.location.reload()">załaduj stronę</a> od nowa.'
1612 },
1613 nl: {
1614 '%PLAY%': 'Afspelen',
1615 '%PAUSE%': 'Pauzeren',
1616 '%REPLAY%': 'Herhaling',
1617 '%NEXT%': 'Volgende',
1618 '%MUTE%': 'Dempen',
1619 '%UNMUTE%': 'Dempen uit',
1620 '%FULL_SCREEN%': 'Volledig scherm',
1621 '%EXIT_FULL_SCREEN%': 'Volledige scherm uit',
1622 '%CHROMECAST%': 'Stream op tv',
1623 '%EXIT_CHROMECAST%': 'Schakel streaming uit',
1624 '%LARGE_PLAYER%': 'Grote Afspeler',
1625 '%SMALL_PLAYER%': 'Kleine Afspeler',
1626 '%QUALITY%': 'Kwaliteit',
1627 '%AUTO_QUALITY%': 'Auto',
1628 '%ADVERTISEMENT_TITLE%': 'Advertentie: Je video zal snel hervat worden',
1629 '%SKIP_AD%': 'Advertentie Overslaan >>',
1630 '%SKIP_TIMER%': 'Je kunt deze video overslaan over % seconden',
1631 '%SHARE%': 'Delen',
1632 '%COPY_EMBED_CODE%': 'Embed Code Kopiëren',
1633 '%COPY_URL_CURRENT_TIME%': 'Video-URL Uit Huidige Tijd Kopiëren',
1634 '%COPY_URL%': 'Video-URL Kopiëren',
1635 '%ABOUT%': 'Debug Info',
1636 '%AUTOPLAY%': 'Autoplay',
1637 '%HOTSPOTS%': 'Hotspots',
1638 '%SLOWMOTION%': 'Slow Motion',
1639 '%HOTSPOTS_HOT_NOT%': "Zie wat heet is en wat niet",
1640 '%NOT_AVAILABLE%': 'Video is niet beschikbaar op dit moment.',
1641 '%ERROR_OCCURED%': 'Een fout deed zich voor, probeer alstublieft later opnieuw of <a href="javascript:window.location.reload()">vernieuw</a> de pagina.'
1642 },
1643 jp: {
1644 '%PLAY%': 'å†Âçâ€Å¸',
1645 '%PAUSE%': '一時åÂϾ¢',
1646 '%REPLAY%': 'リプレイ',
1647 '%NEXT%': '次',
1648 '%MUTE%': 'ミュート',
1649 '%UNMUTE%': 'ミュートを解除',
1650 '%FULL_SCREEN%': 'フルスクリーン',
1651 '%EXIT_FULL_SCREEN%': 'フルスクリーンを終了',
1652 '%CHROMECAST%': 'テレビã§ストリーミング',
1653 '%EXIT_CHROMECAST%': 'ストリーミングを無効ã«ã™る',
1654 '%LARGE_PLAYER%': 'ラージプレーヤー',
1655 '%SMALL_PLAYER%': 'スモールプレーヤー',
1656 '%QUALITY%': '質',
1657 '%AUTO_QUALITY%': '自動',
1658 '%ADVERTISEMENT_TITLE%': '広告:ã‚ãªãŸã®ビデオãÂ΋¾もãªãÂÂå†Âé–‹ã•れã¾ãÂâ„¢',
1659 '%SKIP_AD%': '広告をスã‚Âップ >>',
1660 '%SKIP_TIMER%': '% 秒後ã«ã“ã®ビデオをスã‚Âップã§ãÂÂã¾ãÂâ„¢',
1661 '%SHARE%': '共有',
1662 '%COPY_EMBED_CODE%': '埋ã‚Âè¾¼ã¿コードをコãƒâ€Ã£Æ’¼',
1663 '%COPY_URL_CURRENT_TIME%': 'ç¾時刻ã‹らビデオURLをコãƒâ€Ã£Æ’¼',
1664 '%COPY_URL%': 'ビデオURLをコãƒâ€Ã£Æ’¼',
1665 '%ABOUT%': 'ãƒÂッグ情å ±',
1666 '%AUTOPLAY%': '自動å†Âçâ€Å¸',
1667 '%HOTSPOTS%': 'ホットスãƒÂット',
1668 '%SLOWMOTION%': 'スãƒÂーモーション',
1669 '%HOTSPOTS_HOT_NOT%': '最近ã®æµÂ行り',
1670 '%NOT_AVAILABLE%': 'ç¾在ビデオãŒ利çâ€Â¨Ã£Â§ãÂÂã¾ã›ん。',
1671 '%ERROR_OCCURED%': '<a href="javascript:window.location.reload()">エラーãŒ発çâ€Å¸Ã£Â—ã¾ã—ãŸ。後ã§もã†一度ãŠ試ã—ã«ãªるã‹ã€Âページをå†ÂèªÂè¾¼ã¿ã—ã¦下ã•ã„。</a>'
1672 },
1673 it: {
1674 '%PLAY%': 'Riproduci',
1675 '%PAUSE%': 'Pausa',
1676 '%REPLAY%': 'Replay',
1677 '%NEXT%': 'Successivo',
1678 '%MUTE%': 'Disattiva audio',
1679 '%UNMUTE%': 'Attiva audio',
1680 '%FULL_SCREEN%': 'Schermo intero',
1681 '%EXIT_FULL_SCREEN%': 'Esci da schermo intero',
1682 '%CHROMECAST%': 'Stream in TV',
1683 '%EXIT_CHROMECAST%': 'Disattiva lo streaming',
1684 '%LARGE_PLAYER%': 'Riproduttore grande',
1685 '%SMALL_PLAYER%': 'Riproduttore piccolo',
1686 '%QUALITY%': 'Qualità ',
1687 '%AUTO_QUALITY%': 'Automatico',
1688 '%ADVERTISEMENT_TITLE%': 'Pubblicità : il tuo video riprenderà tra poco',
1689 '%SKIP_AD%': 'Salta pubblicità >>',
1690 '%SKIP_TIMER%': 'Puoi saltare questo video tra % secondi',
1691 '%SHARE%': 'Condividi',
1692 '%COPY_EMBED_CODE%': 'Copia codice integrato',
1693 '%COPY_URL_CURRENT_TIME%': 'Copia URL del video dal tempo corrente',
1694 '%COPY_URL%': 'Copia URL del video',
1695 '%ABOUT%': 'Informazioni di debug',
1696 '%AUTOPLAY%': 'Riproduzione automatica',
1697 '%HOTSPOTS%': 'Hotspot',
1698 '%SLOWMOTION%': 'Rallentatore',
1699 '%HOTSPOTS_HOT_NOT%': 'Scopri cosa piace e cosa no',
1700 '%NOT_AVAILABLE%': 'Il video in questo momento non è disponibile.',
1701 '%ERROR_OCCURED%': 'Si è verificato un errore, riprova più tardi oppure <a href="javascript:window.location.reload()">ricarica</a> la pagina.'
1702 },
1703 de: {
1704 '%PLAY%': 'Spielen',
1705 '%PAUSE%': 'Pause',
1706 '%REPLAY%': 'Wiederholung',
1707 '%NEXT%': 'Weiter',
1708 '%MUTE%': 'Stumm',
1709 '%UNMUTE%': 'Stummschaltung aufheben',
1710 '%FULL_SCREEN%': 'Vollbild',
1711 '%EXIT_FULL_SCREEN%': 'Vollbildansicht verlassen',
1712 '%CHROMECAST%': 'Stream im Fernsehen',
1713 '%EXIT_CHROMECAST%': 'Deaktivieren Sie das Streaming',
1714 '%LARGE_PLAYER%': 'Großer Player',
1715 '%SMALL_PLAYER%': 'Kleiner Player',
1716 '%QUALITY%': 'Qualität',
1717 '%AUTO_QUALITY%': 'Auto',
1718 '%ADVERTISEMENT_TITLE%': 'Werbung: Dein Video wird gleich fortgesetzt',
1719 '%SKIP_AD%': 'Werbung übergehen >>',
1720 '%SKIP_TIMER%': 'Du kannst dieses Video in % Sekunden überspringen',
1721 '%SHARE%': 'teilen',
1722 '%COPY_EMBED_CODE%': 'Eingebetteten Code kopieren',
1723 '%COPY_URL_CURRENT_TIME%': 'Video URL von der aktuellen Zeit kopieren',
1724 '%COPY_URL%': 'Video URL kopieren',
1725 '%ABOUT%': 'Debug-Informationen',
1726 '%AUTOPLAY%': 'Autoplay',
1727 '%HOTSPOTS%': 'Hotspots',
1728 '%SLOWMOTION%': 'Zeitlupe',
1729 '%HOTSPOTS_HOT_NOT%': 'Sieh dir an was in ist und was nicht',
1730 '%NOT_AVAILABLE%': 'Video ist derzeit nicht verfügbar.',
1731 '%ERROR_OCCURED%': 'Ein Fehler ist aufgetreten. Bitte versuche es später oder <a href="javascript:window.location.reload()">lade die</a> Seite erneut.'
1732 },
1733 es: {
1734 '%PLAY%': 'Reproducir',
1735 '%PAUSE%': 'Pausa',
1736 '%REPLAY%': 'Repetición',
1737 '%NEXT%': 'Siguiente',
1738 '%MUTE%': 'Silencio',
1739 '%UNMUTE%': 'Desactivar Silencio',
1740 '%FULL_SCREEN%': 'Pantalla completa',
1741 '%EXIT_FULL_SCREEN%': 'Salir de pantalla completa',
1742 '%CHROMECAST%': 'Corriente en la TV',
1743 '%EXIT_CHROMECAST%': 'Desactivar transmisión',
1744 '%LARGE_PLAYER%': 'Reproductor grande',
1745 '%SMALL_PLAYER%': 'Reproductor pequeño',
1746 '%QUALITY%': 'Calidad',
1747 '%AUTO_QUALITY%': 'Auto',
1748 '%ADVERTISEMENT_TITLE%': 'Publicidad: su video continuará en unos instantes.',
1749 '%SKIP_AD%': 'Saltar publicidad >>',
1750 '%SKIP_TIMER%': 'Puede saltar este video en % segundos.',
1751 '%SHARE%': 'Compartir',
1752 '%COPY_EMBED_CODE%': 'Copiar código incrustado',
1753 '%COPY_URL_CURRENT_TIME%': 'Copiar la URL del video en el instante actual',
1754 '%COPY_URL%': 'Copiar la URL del video',
1755 '%ABOUT%': 'Información de depuración',
1756 '%AUTOPLAY%': 'Auto-reproducción',
1757 '%HOTSPOTS%': 'Hotspots',
1758 '%SLOWMOTION%': 'Camara lenta',
1759 '%HOTSPOTS_HOT_NOT%': 'Ver que es tendencia y que no lo es',
1760 '%NOT_AVAILABLE%': 'El video no está disponible en estos momentos.',
1761 '%ERROR_OCCURED%': 'Ocurrió un error, por favor intente de nuevo o <a href="javascript:window.location.reload()">recargue</a> la página.'
1762 },
1763 cz: {
1764 '%PLAY%': 'Přehrát',
1765 '%PAUSE%': 'Pozastavit',
1766 '%REPLAY%': 'Přehrát',
1767 '%NEXT%': 'DalÅ¡ÃÂ',
1768 '%MUTE%': 'Ztlumit',
1769 '%UNMUTE%': 'ZesÃÂlit',
1770 '%FULL_SCREEN%': 'Celá obrazovka',
1771 '%EXIT_FULL_SCREEN%': 'Vypnout režim celé obrazovky',
1772 '%CHROMECAST%': 'Stream v televizi',
1773 '%EXIT_CHROMECAST%': 'ZakázánàstreamovánÃÂ',
1774 '%LARGE_PLAYER%': 'Velký pÃ…â„¢ehrávaÄÂ',
1775 '%SMALL_PLAYER%': 'Malý pÃ…â„¢ehrávaÄÂ',
1776 '%QUALITY%': 'Kvalita',
1777 '%AUTO_QUALITY%': 'Auto',
1778 '%ADVERTISEMENT_TITLE%': 'Reklama: VaÅ¡e video bude brzy pokraÄÂovat',
1779 '%SKIP_AD%': 'PÃ…â„¢eskoÄÂit reklamu >>',
1780 '%SKIP_TIMER%': 'Můžete pÃ…â„¢eskoÄÂit video za % sekund',
1781 '%SHARE%': 'SdÃÂlet',
1782 '%COPY_EMBED_CODE%': 'KopÃÂrovat embed kód',
1783 '%COPY_URL_CURRENT_TIME%': 'KopÃÂrovat URL videa od aktuálnÃÂho ÄÂasu',
1784 '%COPY_URL%': 'KopÃÂrovat URL videa',
1785 '%ABOUT%': 'Informace o ladÄ›nÃÂ',
1786 '%AUTOPLAY%': 'Automatické pÃ…â„¢ehrávánÃÂ',
1787 '%HOTSPOTS%': 'Hotspoty',
1788 '%SLOWMOTION%': 'Zpomalený pohyb',
1789 '%HOTSPOTS_HOT_NOT%': 'PodÃÂvejte se, co je žhavé a co ne',
1790 '%NOT_AVAILABLE%': 'Video nenàmomentálně dostupné.',
1791 '%ERROR_OCCURED%': 'Objevila se chyba, zkuste to prosÃÂm pozdÄ›ji nebo <a href="javascript:window.location.reload()">obnovte</a> stránku.'
1792 }
1793 };
1794
1795 window.MHP1138 = window.MHP1138 || {};
1796 window.MHP1138.Locales = Locales;
1797})(window);
1798// Copyright Google Inc. All Rights Reserved.
1799// MODIFIED by Alex Strelets, see PresentationRequest check at the beginning
1800(function() { 'use strict';if(!window.PresentationRequest)return;
1801 var f,g=function(a,b){function c(){}c.prototype=b.prototype;a.Kb=b.prototype;a.prototype=new c;a.prototype.constructor=a;for(var d in b)if(Object.defineProperties){var e=Object.getOwnPropertyDescriptor(b,d);e&&Object.defineProperty(a,d,e)}else a[d]=b[d]},aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},h="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:
1802 this,ca=function(){ca=function(){};h.Symbol||(h.Symbol=da)},ea=0,da=function(a){return"jscomp_symbol_"+(a||"")+ea++},ga=function(){ca();var a=h.Symbol.iterator;a||(a=h.Symbol.iterator=h.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&aa(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return fa(this)}});ga=function(){}},fa=function(a){var b=0;return ha(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})},ha=function(a){ga();a={next:a};a[h.Symbol.iterator]=function(){return this};
1803 return a},ia=function(a){ga();var b=a[Symbol.iterator];return b?b.call(a):fa(a)},k=this,n=function(){},ja=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||
1804 "undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},ka=function(a){var b=ja(a);return"array"==b||"object"==b&&"number"==typeof a.length},p=function(a){return"function"==ja(a)},la=function(a,b,c){return a.call.apply(a.bind,arguments)},ma=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,
1805 2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}},r=function(a,b,c){r=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?la:ma;return r.apply(null,arguments)},na=Date.now||function(){return+new Date},t=function(a,b){a=a.split(".");var c=k;a[0]in c||!c.execScript||c.execScript("var "+a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?
1806 c=c[d]&&c[d]!==Object.prototype[d]?c[d]:c[d]={}:c[d]=b},u=function(a,b){function c(){}c.prototype=b.prototype;a.Kb=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.Ob=function(a,c,m){for(var d=Array(arguments.length-2),e=2;e<arguments.length;e++)d[e-2]=arguments[e];return b.prototype[c].apply(a,d)}};var v=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,v);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))};u(v,Error);v.prototype.name="CustomError";var oa=function(a,b){for(var c=a.split("%s"),d="",e=Array.prototype.slice.call(arguments,1);e.length&&1<c.length;)d+=c.shift()+e.shift();return d+c.join("%s")},pa=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},qa=function(a,b){return a<b?-1:a>b?1:0};var ra=function(a,b){b.unshift(a);v.call(this,oa.apply(null,b));b.shift()};u(ra,v);ra.prototype.name="AssertionError";var sa=function(a,b){throw new ra("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1));};var w;a:{var ta=k.navigator;if(ta){var ua=ta.userAgent;if(ua){w=ua;break a}}w=""}var x=function(a){return-1!=w.indexOf(a)};var wa=function(a,b){var c=va;return Object.prototype.hasOwnProperty.call(c,a)?c[a]:c[a]=b(a)};var xa=x("Opera"),y=x("Trident")||x("MSIE"),ya=x("Edge"),za=x("Gecko")&&!(-1!=w.toLowerCase().indexOf("webkit")&&!x("Edge"))&&!(x("Trident")||x("MSIE"))&&!x("Edge"),Aa=-1!=w.toLowerCase().indexOf("webkit")&&!x("Edge"),Ba;
1807 a:{var Ca="",Da=function(){var a=w;if(za)return/rv\:([^\);]+)(\)|;)/.exec(a);if(ya)return/Edge\/([\d\.]+)/.exec(a);if(y)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(Aa)return/WebKit\/(\S+)/.exec(a);if(xa)return/(?:Version)[ \/]?(\S+)/.exec(a)}();Da&&(Ca=Da?Da[1]:"");if(y){var z,Ea=k.document;z=Ea?Ea.documentMode:void 0;if(null!=z&&z>parseFloat(Ca)){Ba=String(z);break a}}Ba=Ca}
1808 var Fa=Ba,va={},A=function(a){return wa(a,function(){for(var b=0,c=pa(String(Fa)).split("."),d=pa(String(a)).split("."),e=Math.max(c.length,d.length),m=0;0==b&&m<e;m++){var l=c[m]||"",q=d[m]||"";do{l=/(\d*)(\D*)(.*)/.exec(l)||["","","",""];q=/(\d*)(\D*)(.*)/.exec(q)||["","","",""];if(0==l[0].length&&0==q[0].length)break;b=qa(0==l[1].length?0:parseInt(l[1],10),0==q[1].length?0:parseInt(q[1],10))||qa(0==l[2].length,0==q[2].length)||qa(l[2],q[2]);l=l[3];q=q[3]}while(0==b)}return 0<=b})};var B=function(a,b,c,d,e){this.reset(a,b,c,d,e)};B.prototype.ga=null;var Ga=0;B.prototype.reset=function(a,b,c,d,e){"number"==typeof e||Ga++;this.Sa=d||na();this.w=a;this.Ha=b;this.Fa=c;delete this.ga};B.prototype.xa=function(a){this.w=a};var C=function(a){this.Ia=a;this.N=this.ea=this.w=this.j=null},D=function(a,b){this.name=a;this.value=b};D.prototype.toString=function(){return this.name};
1809 var Ha=new D("SHOUT",1200),E=new D("SEVERE",1E3),Ia=new D("WARNING",900),Ja=new D("INFO",800),Ka=new D("CONFIG",700),La=[new D("OFF",Infinity),Ha,E,Ia,Ja,Ka,new D("FINE",500),new D("FINER",400),new D("FINEST",300),new D("ALL",0)],F=null,Ma=function(a){if(!F){F={};for(var b=0,c;c=La[b];b++)F[c.value]=c,F[c.name]=c}if(a in F)return F[a];for(b=0;b<La.length;++b)if(c=La[b],c.value<=a)return c;return null};C.prototype.getName=function(){return this.Ia};C.prototype.getParent=function(){return this.j};
1810 C.prototype.xa=function(a){this.w=a};var Na=function(a){if(a.w)return a.w;if(a.j)return Na(a.j);sa("Root logger has no level set.");return null};C.prototype.log=function(a,b,c){if(a.value>=Na(this).value)for(p(b)&&(b=b()),a=new B(a,String(b),this.Ia),c&&(a.ga=c),c="log:"+a.Ha,k.console&&(k.console.timeStamp?k.console.timeStamp(c):k.console.markTimeline&&k.console.markTimeline(c)),k.msWriteProfilerMark&&k.msWriteProfilerMark(c),c=this;c;){var d=c,e=a;if(d.N)for(var m=0;b=d.N[m];m++)b(e);c=c.getParent()}};
1811 C.prototype.info=function(a,b){this.log(Ja,a,b)};var Oa={},G=null,Pa=function(){G||(G=new C(""),Oa[""]=G,G.xa(Ka))},Qa=function(){Pa();return G},H=function(a){Pa();var b;if(!(b=Oa[a])){b=new C(a);var c=a.lastIndexOf("."),d=a.substr(c+1),c=H(a.substr(0,c));c.ea||(c.ea={});c.ea[d]=b;b.j=c;Oa[a]=b}return b};var I=function(a){var b=Ra;b&&b.log(Ia,a,void 0)};var J=function(){this.Ma=na()},Sa=new J;J.prototype.set=function(a){this.Ma=a};J.prototype.reset=function(){this.set(na())};J.prototype.get=function(){return this.Ma};var Ta=function(a){this.yb=a||"";this.Jb=Sa};f=Ta.prototype;f.za=!0;f.Qa=!0;f.Hb=!0;f.Gb=!0;f.Ra=!1;f.Ib=!1;var K=function(a){return 10>a?"0"+a:String(a)},Ua=function(a,b){a=(a.Sa-b)/1E3;b=a.toFixed(3);var c=0;if(1>a)c=2;else for(;100>a;)c++,a*=10;for(;0<c--;)b=" "+b;return b},Va=function(a){Ta.call(this,a)};u(Va,Ta);var Wa=function(){this.zb=r(this.Ta,this);this.V=new Va;this.V.Qa=!1;this.V.Ra=!1;this.Ea=this.V.za=!1;this.bb={}};
1812 Wa.prototype.Ta=function(a){if(!this.bb[a.Fa]){var b=this.V;var c=[];c.push(b.yb," ");if(b.Qa){var d=new Date(a.Sa);c.push("[",K(d.getFullYear()-2E3)+K(d.getMonth()+1)+K(d.getDate())+" "+K(d.getHours())+":"+K(d.getMinutes())+":"+K(d.getSeconds())+"."+K(Math.floor(d.getMilliseconds()/10)),"] ")}b.Hb&&c.push("[",Ua(a,b.Jb.get()),"s] ");b.Gb&&c.push("[",a.Fa,"] ");b.Ib&&c.push("[",a.w.name,"] ");c.push(a.Ha);b.Ra&&(d=a.ga)&&c.push("\n",d instanceof Error?d.message:d.toString());b.za&&c.push("\n");b=
1813 c.join("");if(c=Xa)switch(a.w){case Ha:M(c,"info",b);break;case E:M(c,"error",b);break;case Ia:M(c,"warn",b);break;default:M(c,"debug",b)}}};var N=null,Xa=k.console,M=function(a,b,c){if(a[b])a[b](c);else a.log(c)};var Ya=function(a,b,c){this.pb=c;this.Xa=a;this.Cb=b;this.$=0;this.X=null};Ya.prototype.get=function(){if(0<this.$){this.$--;var a=this.X;this.X=a.next;a.next=null}else a=this.Xa();return a};Ya.prototype.put=function(a){this.Cb(a);this.$<this.pb&&(this.$++,a.next=this.X,this.X=a)};var Za=function(a){k.setTimeout(function(){throw a;},0)},$a,ab=function(){var a=k.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&!x("Presto")&&(a=function(){var a=document.createElement("IFRAME");a.style.display="none";a.src="";document.documentElement.appendChild(a);var b=a.contentWindow,a=b.document;a.open();a.write("");a.close();var c="callImmediate"+Math.random(),d="file:"==b.location.protocol?"*":b.location.protocol+"//"+b.location.host,
1814 a=r(function(a){if(("*"==d||a.origin==d)&&a.data==c)this.port1.onmessage()},this);b.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){b.postMessage(c,d)}}});if("undefined"!==typeof a&&!x("Trident")&&!x("MSIE")){var b=new a,c={},d=c;b.port1.onmessage=function(){if(void 0!==c.next){c=c.next;var a=c.Aa;c.Aa=null;a()}};return function(a){d.next={Aa:a};d=d.next;b.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement("SCRIPT")?
1815 function(a){var b=document.createElement("SCRIPT");b.onreadystatechange=function(){b.onreadystatechange=null;b.parentNode.removeChild(b);b=null;a();a=null};document.documentElement.appendChild(b)}:function(a){k.setTimeout(a,0)}};var bb=function(){this.ba=this.K=null},db=new Ya(function(){return new cb},function(a){a.reset()},100);bb.prototype.add=function(a,b){var c=db.get();c.set(a,b);this.ba?this.ba.next=c:this.K=c;this.ba=c};bb.prototype.remove=function(){var a=null;this.K&&(a=this.K,this.K=this.K.next,this.K||(this.ba=null),a.next=null);return a};var cb=function(){this.next=this.scope=this.ia=null};cb.prototype.set=function(a,b){this.ia=a;this.scope=b;this.next=null};
1816 cb.prototype.reset=function(){this.next=this.scope=this.ia=null};var ib=function(a,b){eb||fb();gb||(eb(),gb=!0);hb.add(a,b)},eb,fb=function(){if(-1!=String(k.Promise).indexOf("[native code]")){var a=k.Promise.resolve(void 0);eb=function(){a.then(jb)}}else eb=function(){var a=jb;!p(k.setImmediate)||k.Window&&k.Window.prototype&&!x("Edge")&&k.Window.prototype.setImmediate==k.setImmediate?($a||($a=ab()),$a(a)):k.setImmediate(a)}},gb=!1,hb=new bb,jb=function(){for(var a;a=hb.remove();){try{a.ia.call(a.scope)}catch(b){Za(b)}db.put(a)}gb=!1};var Q=function(a,b){this.g=0;this.Na=void 0;this.B=this.o=this.j=null;this.W=this.ha=!1;if(a!=n)try{var c=this;a.call(b,function(a){O(c,2,a)},function(a){if(!(a instanceof P))try{if(a instanceof Error)throw a;throw Error("Promise rejected.");}catch(e){}O(c,3,a)})}catch(d){O(this,3,d)}},kb=function(){this.next=this.context=this.F=this.P=this.v=null;this.U=!1};kb.prototype.reset=function(){this.context=this.F=this.P=this.v=null;this.U=!1};
1817 var lb=new Ya(function(){return new kb},function(a){a.reset()},100),mb=function(a,b,c){var d=lb.get();d.P=a;d.F=b;d.context=c;return d},R=function(){var a,b,c=new Q(function(c,e){a=c;b=e});return new nb(c,a,b)};Q.prototype.then=function(a,b,c){return ob(this,p(a)?a:null,p(b)?b:null,c)};Q.prototype.then=Q.prototype.then;Q.prototype.$goog_Thenable=!0;Q.prototype.cancel=function(a){0==this.g&&ib(function(){var b=new P(a);pb(this,b)},this)};
1818 var pb=function(a,b){if(0==a.g)if(a.j){var c=a.j;if(c.o){for(var d=0,e=null,m=null,l=c.o;l&&(l.U||(d++,l.v==a&&(e=l),!(e&&1<d)));l=l.next)e||(m=l);e&&(0==c.g&&1==d?pb(c,b):(m?(d=m,d.next==c.B&&(c.B=d),d.next=d.next.next):qb(c),rb(c,e,3,b)))}a.j=null}else O(a,3,b)},tb=function(a,b){a.o||2!=a.g&&3!=a.g||sb(a);a.B?a.B.next=b:a.o=b;a.B=b},ob=function(a,b,c,d){var e=mb(null,null,null);e.v=new Q(function(a,l){e.P=b?function(c){try{var e=b.call(d,c);a(e)}catch(L){l(L)}}:a;e.F=c?function(b){try{var e=c.call(d,
1819 b);void 0===e&&b instanceof P?l(b):a(e)}catch(L){l(L)}}:l});e.v.j=a;tb(a,e);return e.v};Q.prototype.Lb=function(a){this.g=0;O(this,2,a)};Q.prototype.Mb=function(a){this.g=0;O(this,3,a)};
1820 var O=function(a,b,c){if(0==a.g){a===c&&(b=3,c=new TypeError("Promise cannot resolve to itself"));a.g=1;a:{var d=c,e=a.Lb,m=a.Mb;if(d instanceof Q){tb(d,mb(e||n,m||null,a));var l=!0}else{if(d)try{var q=!!d.$goog_Thenable}catch(L){q=!1}else q=!1;if(q)d.then(e,m,a),l=!0;else{q=typeof d;if("object"==q&&null!=d||"function"==q)try{var ba=d.then;if(p(ba)){ub(d,ba,e,m,a);l=!0;break a}}catch(L){m.call(a,L);l=!0;break a}l=!1}}}l||(a.Na=c,a.g=b,a.j=null,sb(a),3!=b||c instanceof P||vb(a,c))}},ub=function(a,
1821b,c,d,e){var m=!1,l=function(a){m||(m=!0,c.call(e,a))},q=function(a){m||(m=!0,d.call(e,a))};try{b.call(a,l,q)}catch(ba){q(ba)}},sb=function(a){a.ha||(a.ha=!0,ib(a.$a,a))},qb=function(a){var b=null;a.o&&(b=a.o,a.o=b.next,b.next=null);a.o||(a.B=null);return b};Q.prototype.$a=function(){for(var a;a=qb(this);)rb(this,a,this.g,this.Na);this.ha=!1};
1822 var rb=function(a,b,c,d){if(3==c&&b.F&&!b.U)for(;a&&a.W;a=a.j)a.W=!1;if(b.v)b.v.j=null,wb(b,c,d);else try{b.U?b.P.call(b.context):wb(b,c,d)}catch(e){xb.call(null,e)}lb.put(b)},wb=function(a,b,c){2==b?a.P.call(a.context,c):a.F&&a.F.call(a.context,c)},vb=function(a,b){a.W=!0;ib(function(){a.W&&xb.call(null,b)})},xb=Za,P=function(a){v.call(this,a)};u(P,v);P.prototype.name="cancel";var nb=function(a,b,c){this.I=a;this.resolve=b;this.reject=c};var yb=function(){this.Ca=this.Ca;this.vb=this.vb};yb.prototype.Ca=!1;y&&A("9");!Aa||A("528");za&&A("1.9b")||y&&A("8")||xa&&A("9.5")||Aa&&A("528");za&&!A("8")||y&&A("9");var zb=function(a,b,c){yb.call(this);this.qb=null!=c?r(a,c):a;this.ob=b;this.Wa=r(this.xb,this);this.da=[]};u(zb,yb);f=zb.prototype;f.J=!1;f.R=0;f.A=null;f.cb=function(a){this.da=arguments;this.A||this.R?this.J=!0:Ab(this)};f.stop=function(){this.A&&(k.clearTimeout(this.A),this.A=null,this.J=!1,this.da=[])};f.pause=function(){this.R++};f.resume=function(){this.R--;this.R||!this.J||this.A||(this.J=!1,Ab(this))};f.xb=function(){this.A=null;this.J&&!this.R&&(this.J=!1,Ab(this))};
1823 var Ab=function(a){var b=a.Wa;var c=a.ob;if(!p(b))if(b&&"function"==typeof b.handleEvent)b=r(b.handleEvent,b);else throw Error("Invalid listener argument");b=2147483647<Number(c)?-1:k.setTimeout(b,c||0);a.A=b;a.qb.apply(null,a.da)};var S=function(a){a.controller=this;this.a=a;this.s=this.f=this.b=null;this.Ka=this.wb.bind(this);this.C=this.sb.bind(this);this.D=this.tb.bind(this);this.m=0;this.Nb=new zb(this.ab,200,this)};f=S.prototype;f.ta=function(){this.f&&(this.m++,this.a.isPaused=!this.a.isPaused,this.a.isPaused?this.f.pause(null,this.D,this.C):this.f.play(null,this.D,this.C))};f.stop=function(){this.f&&(this.m++,this.f.stop(null,this.D,this.C))};
1824 f.seek=function(){if(this.f){this.s&&(clearTimeout(this.s),this.s=null);this.m++;var a=new chrome.cast.media.SeekRequest;a.currentTime=this.a.currentTime;this.f.seek(a,this.D,this.C)}};f.ra=function(){this.m++;this.a.isMuted=!this.a.isMuted;this.b.setReceiverMuted(this.a.isMuted,this.D,this.C)};f.ya=function(){this.Nb.cb()};f.ab=function(){this.m++;this.b.setReceiverVolumeLevel(this.a.volumeLevel,this.D,this.C)};f.tb=function(){this.m--;this.u()};
1825 f.sb=function(){this.m--;this.f&&this.f.getStatus(null,n,n)};f.wb=function(){this.f&&(this.a.currentTime=this.f.getEstimatedTime(),this.s=setTimeout(this.Ka,1E3))};
1826 f.u=function(a){if(!(0<this.m))if(this.b){this.a.displayName=this.b.displayName||"";var b=this.b.statusText||"";this.a.displayStatus=b!=this.a.displayName?b:"";!a&&this.b.receiver&&(a=this.b.receiver.volume)&&(null!=a.muted&&(this.a.isMuted=a.muted),null!=a.level&&(this.a.volumeLevel=a.level),this.a.canControlVolume="fixed"!=a.controlType);this.f?(this.a.isMediaLoaded=this.f.playerState!=chrome.cast.media.PlayerState.IDLE,this.a.isPaused=this.f.playerState==chrome.cast.media.PlayerState.PAUSED,this.a.canPause=
1827 0<=this.f.supportedMediaCommands.indexOf(chrome.cast.media.MediaCommand.PAUSE),this.T(this.f.media),this.a.canSeek=0<=this.f.supportedMediaCommands.indexOf(chrome.cast.media.MediaCommand.SEEK)&&0!=this.a.duration,this.a.currentTime=this.f.getEstimatedTime(),this.s&&(clearTimeout(this.s),this.s=null),this.f.playerState==chrome.cast.media.PlayerState.PLAYING&&(this.s=setTimeout(this.Ka,1E3))):this.T(null)}else this.a.displayName="",this.a.displayStatus="",this.T(null)};
1828 f.T=function(a){a?(this.a.duration=a.duration||0,a.metadata&&a.metadata.title&&(this.a.displayStatus=a.metadata.title)):(this.a.isMediaLoaded=!1,this.a.canPause=!1,this.a.canSeek=!1,this.a.currentTime=0,this.a.duration=0)};var Bb=function(a){if(!a.f)for(var b=0,c=a.b.media;b<c.length;b++)if(!c[b].idleReason){a.f=c[b];a.f.addUpdateListener(a.rb.bind(a));break}},Cb=function(a,b){a.b=b;b.addMediaListener(a.Ga.bind(a));b.addUpdateListener(a.wa.bind(a));Bb(a);a.u()};f=S.prototype;
1829 f.wa=function(a){a||(this.f=this.b=null);this.u()};f.Ga=function(){Bb(this);this.u(!0)};f.rb=function(a){a||(this.f=null);this.u(!0)};f.ka=function(a,b){return b?100*a/b:0};f.la=function(a,b){return b?a*b/100:0};f.ja=function(a){return 0>a?"":[("0"+Math.floor(a/3600)).substr(-2),("0"+Math.floor(a/60)%60).substr(-2),("0"+Math.floor(a)%60).substr(-2)].join(":")};var Db=H("cast.common.loadScript"),Eb=function(){new Promise(function(a,b){var c=document.createElement("script");c.type="text/javascript";c.src="https://www.gstatic.com/external_hosted/polymer/v1/webcomponents.min.js";c.onload=function(){Db&&Db.info("library(https://www.gstatic.com/external_hosted/polymer/v1/webcomponents.min.js is loaded",void 0);a()};c.onerror=function(){Db&&Db.log(E,"library(https://www.gstatic.com/external_hosted/polymer/v1/webcomponents.min.js) failed to load",void 0);b()};
1830 (document.head||document.body||document).appendChild(c)})};t("cast.framework.VERSION","1.0.05");t("cast.framework.LoggerLevel",{DEBUG:0,INFO:800,WARNING:900,ERROR:1E3,NONE:1500});t("cast.framework.CastState",{NO_DEVICES_AVAILABLE:"NO_DEVICES_AVAILABLE",NOT_CONNECTED:"NOT_CONNECTED",CONNECTING:"CONNECTING",CONNECTED:"CONNECTED"});
1831 t("cast.framework.SessionState",{NO_SESSION:"NO_SESSION",SESSION_STARTING:"SESSION_STARTING",SESSION_STARTED:"SESSION_STARTED",SESSION_START_FAILED:"SESSION_START_FAILED",SESSION_ENDING:"SESSION_ENDING",SESSION_ENDED:"SESSION_ENDED",SESSION_RESUMED:"SESSION_RESUMED"});t("cast.framework.CastContextEventType",{CAST_STATE_CHANGED:"caststatechanged",SESSION_STATE_CHANGED:"sessionstatechanged"});
1832 t("cast.framework.SessionEventType",{APPLICATION_STATUS_CHANGED:"applicationstatuschanged",APPLICATION_METADATA_CHANGED:"applicationmetadatachanged",ACTIVE_INPUT_STATE_CHANGED:"activeinputstatechanged",VOLUME_CHANGED:"volumechanged",MEDIA_SESSION:"mediasession"});
1833 t("cast.framework.RemotePlayerEventType",{ANY_CHANGE:"anyChanged",IS_CONNECTED_CHANGED:"isConnectedChanged",IS_MEDIA_LOADED_CHANGED:"isMediaLoadedChanged",DURATION_CHANGED:"durationChanged",CURRENT_TIME_CHANGED:"currentTimeChanged",IS_PAUSED_CHANGED:"isPausedChanged",VOLUME_LEVEL_CHANGED:"volumeLevelChanged",CAN_CONTROL_VOLUME_CHANGED:"canControlVolumeChanged",IS_MUTED_CHANGED:"isMutedChanged",CAN_PAUSE_CHANGED:"canPauseChanged",CAN_SEEK_CHANGED:"canSeekChanged",DISPLAY_NAME_CHANGED:"displayNameChanged",
1834 STATUS_TEXT_CHANGED:"statusTextChanged",TITLE_CHANGED:"titleChanged",DISPLAY_STATUS_CHANGED:"displayStatusChanged",MEDIA_INFO_CHANGED:"mediaInfoChanged",IMAGE_URL_CHANGED:"imageUrlChanged",PLAYER_STATE_CHANGED:"playerStateChanged"});t("cast.framework.ActiveInputState",{ACTIVE_INPUT_STATE_UNKNOWN:-1,ACTIVE_INPUT_STATE_NO:0,ACTIVE_INPUT_STATE_YES:1});var Fb=function(a){Qa().xa(Ma(a))};t("cast.framework.setLoggerLevel",Fb);N||(N=new Wa);
1835 if(N){var Gb=N;if(1!=Gb.Ea){var Hb=Qa(),Ib=Gb.zb;Hb.N||(Hb.N=[]);Hb.N.push(Ib);Gb.Ea=!0}}Fb(1E3);var T=function(a){this.type=a};t("cast.framework.EventData",T);var Jb=function(a){this.type="activeinputstatechanged";this.activeInputState=a};g(Jb,T);t("cast.framework.ActiveInputStateEventData",Jb);var Kb=function(a){this.applicationId=a.appId;this.name=a.displayName;this.images=a.appImages;this.namespaces=this.sa(a.namespaces||[])};t("cast.framework.ApplicationMetadata",Kb);Kb.prototype.sa=function(a){return a.map(function(a){return a.name})};var Lb=function(a){this.type="applicationmetadatachanged";this.metadata=a};g(Lb,T);t("cast.framework.ApplicationMetadataEventData",Lb);var Mb=function(a){this.type="applicationstatuschanged";this.status=a};g(Mb,T);t("cast.framework.ApplicationStatusEventData",Mb);var Nb=H("cast.framework.EventTarget"),U=function(){this.O={}};U.prototype.addEventListener=function(a,b){a in this.O||(this.O[a]=[]);a=this.O[a];a.includes(b)||a.push(b)};U.prototype.removeEventListener=function(a,b){a=this.O[a]||[];b=a.indexOf(b);0<=b&&a.splice(b,1)};U.prototype.dispatchEvent=function(a){a&&a.type&&(this.O[a.type]||[]).forEach(function(b){try{b(a)}catch(c){Nb&&Nb.log(E,"Handler for "+a.type+" event failed: "+c,c)}})};var Ob=function(a){a=a||{};this.receiverApplicationId=a.receiverApplicationId||null;this.resumeSavedSession=void 0!==a.resumeSavedSession?a.resumeSavedSession:!0;this.autoJoinPolicy=void 0!==a.autoJoinPolicy?a.autoJoinPolicy:chrome.cast.AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED;this.language=a.language||null};t("cast.framework.CastOptions",Ob);var Pb=function(a){this.type="mediasession";this.mediaSession=a};g(Pb,T);t("cast.framework.MediaSessionEventData",Pb);var Qb=function(a,b){this.type="volumechanged";this.volume=a;this.isMute=b};g(Qb,T);t("cast.framework.VolumeEventData",Qb);var V=function(a,b){this.h=new U;this.g=b;this.c=a;this.Oa=a.sessionId;this.S=a.statusText;this.La=a.receiver;this.i=a.receiver.volume;this.Z=new Kb(a);this.Y=a.receiver.isActiveInput;a:{a=this.c;if(a.media)for(a=ia(a.media),b=a.next();!b.done;b=a.next())if(b=b.value,!b.idleReason){a=b;break a}a=null}this.qa=a;this.c.addMediaListener(this.pa.bind(this));Rb(this)};t("cast.framework.CastSession",V);
1836 var Rb=function(a){var b=a.c.loadMedia.bind(a.c);a.c.loadMedia=function(c,e,m){b(c,function(b){e&&e(b);a.pa(b)},m)};var c=a.c.queueLoad.bind(a.c);a.c.queueLoad=function(b,e,m){c(b,function(b){e&&e(b);a.pa(b)},m)}};V.prototype.addEventListener=function(a,b){this.h.addEventListener(a,b)};V.prototype.addEventListener=V.prototype.addEventListener;V.prototype.removeEventListener=function(a,b){this.h.removeEventListener(a,b)};V.prototype.removeEventListener=V.prototype.removeEventListener;
1837 var Tb=function(a,b){a.La=b;!b.volume||a.i&&a.i.muted==b.volume.muted&&a.i.level==b.volume.level||(a.i=b.volume,a.h.dispatchEvent(new Qb(a.i.level,a.i.muted)));a.Y!=b.isActiveInput&&(a.Y=b.isActiveInput,a.h.dispatchEvent(new Jb(Sb(a.Y))))};V.prototype.mb=function(){return this.c};V.prototype.getSessionObj=V.prototype.mb;V.prototype.lb=function(){return this.Oa};V.prototype.getSessionId=V.prototype.lb;V.prototype.ma=function(){return this.g};V.prototype.getSessionState=V.prototype.ma;
1838 V.prototype.hb=function(){return this.La};V.prototype.getCastDevice=V.prototype.hb;V.prototype.fb=function(){return this.Z};V.prototype.getApplicationMetadata=V.prototype.fb;V.prototype.gb=function(){return this.S};V.prototype.getApplicationStatus=V.prototype.gb;V.prototype.eb=function(){return Sb(this.Y)};V.prototype.getActiveInputState=V.prototype.eb;V.prototype.Da=function(a){"SESSION_ENDED"!=this.g&&(a?this.c.stop(n,n):this.c.leave(n,n))};V.prototype.endSession=V.prototype.Da;
1839 V.prototype.setVolume=function(a){var b=R(),c=Promise.resolve(b.I);this.i&&(this.i.level=a,this.i.muted=!1);this.c.setReceiverVolumeLevel(a,function(){return b.resolve()},function(a){return b.reject(a.code)});return c};V.prototype.setVolume=V.prototype.setVolume;V.prototype.nb=function(){return this.i?this.i.level:null};V.prototype.getVolume=V.prototype.nb;
1840 V.prototype.Eb=function(a){var b=R(),c=Promise.resolve(b.I);this.i&&(this.i.muted=a);this.c.setReceiverMuted(a,function(){return b.resolve()},function(a){return b.reject(a.code)});return c};V.prototype.setMute=V.prototype.Eb;V.prototype.isMute=function(){return this.i?this.i.muted:null};V.prototype.isMute=V.prototype.isMute;V.prototype.sendMessage=function(a,b){var c=R(),d=Promise.resolve(c.I);this.c.sendMessage(a,b,function(){return c.resolve()},function(a){return c.reject(a.code)});return d};
1841 V.prototype.sendMessage=V.prototype.sendMessage;V.prototype.addMessageListener=function(a,b){this.c.addMessageListener(a,b)};V.prototype.addMessageListener=V.prototype.addMessageListener;V.prototype.removeMessageListener=function(a,b){this.c.removeMessageListener(a,b)};V.prototype.removeMessageListener=V.prototype.removeMessageListener;V.prototype.loadMedia=function(a){var b=R(),c=Promise.resolve(b.I);this.c.loadMedia(a,function(){b.resolve()},function(a){b.reject(a.code)});return c};
1842 V.prototype.loadMedia=V.prototype.loadMedia;V.prototype.kb=function(){return this.qa};V.prototype.getMediaSession=V.prototype.kb;V.prototype.pa=function(a){a.media&&(this.qa=a,this.h.dispatchEvent(new Pb(a)))};var Sb=function(a){return null==a?-1:a?1:0};V.prototype.sa=function(a){return a.map(function(a,c){return c.name})};var Ub=function(a){this.type="caststatechanged";this.castState=a};g(Ub,T);t("cast.framework.CastStateEventData",Ub);var Vb=function(a,b,c){this.type="sessionstatechanged";this.session=a;this.sessionState=b;this.errorCode=void 0!==c?c:null};g(Vb,T);t("cast.framework.SessionStateEventData",Vb);var Ra=H("cast.framework.CastContext"),W=function(){this.h=new U;this.oa=!1;this.G=null;this.va=!1;this.L="NO_DEVICES_AVAILABLE";this.l="NO_SESSION";this.aa=this.b=null};t("cast.framework.CastContext",W);W.prototype.addEventListener=function(a,b){this.h.addEventListener(a,b)};W.prototype.addEventListener=W.prototype.addEventListener;W.prototype.removeEventListener=function(a,b){this.h.removeEventListener(a,b)};W.prototype.removeEventListener=W.prototype.removeEventListener;
1843 W.prototype.Fb=function(a){if(this.oa)I("CastContext already initialized, new options are ignored");else{this.G=new Ob(a);if(!this.G||!this.G.receiverApplicationId)throw Error("Missing application id in cast options");a=new chrome.cast.SessionRequest(this.G.receiverApplicationId);a=new chrome.cast.ApiConfig(a,this.Pa.bind(this),this.Bb.bind(this),this.G.autoJoinPolicy);chrome.cast.initialize(a,n,n);chrome.cast.addReceiverActionListener(this.Ab.bind(this));this.oa=!0}};W.prototype.setOptions=W.prototype.Fb;
1844 W.prototype.ib=function(){return this.L};W.prototype.getCastState=W.prototype.ib;W.prototype.ma=function(){return this.l};W.prototype.getSessionState=W.prototype.ma;
1845 W.prototype.requestSession=function(){var a=this;if(!this.oa)throw Error("Cannot start session before cast options are provided");var b=R(),c=Promise.resolve(b.I);ob(b.I,null,n,void 0);c.catch(n);var d="NOT_CONNECTED"==this.L;chrome.cast.requestSession(function(c){a.Pa(c);b.resolve(null)},function(c){d&&X(a,"SESSION_START_FAILED",c?c.code:void 0);b.reject(c.code)});return c};W.prototype.requestSession=W.prototype.requestSession;W.prototype.jb=function(){return this.b};
1846 W.prototype.getCurrentSession=W.prototype.jb;W.prototype.Za=function(a){this.b&&this.b.Da(a)};W.prototype.endCurrentSession=W.prototype.Za;W.prototype.Bb=function(a){(this.va=a==chrome.cast.ReceiverAvailability.AVAILABLE)&&!this.b&&this.aa&&this.G.resumeSavedSession&&chrome.cast.requestSessionById(this.aa);Wb(this)};W.prototype.Ab=function(a,b){this.b||b!=chrome.cast.ReceiverAction.CAST?this.b&&b==chrome.cast.ReceiverAction.STOP?X(this,"SESSION_ENDING"):a&&Tb(this.b,a):X(this,"SESSION_STARTING")};
1847 W.prototype.Pa=function(a){var b="SESSION_STARTING"==this.l?"SESSION_STARTED":"SESSION_RESUMED";this.aa=null;this.b=new V(a,b);a.addUpdateListener(this.wa.bind(this));X(this,b)};
1848 W.prototype.wa=function(){if(this.b)switch(this.b.c.status){case chrome.cast.SessionStatus.DISCONNECTED:case chrome.cast.SessionStatus.STOPPED:X(this,"SESSION_ENDED");this.aa=this.b.Oa;this.b=null;break;case chrome.cast.SessionStatus.CONNECTED:var a=this.b,b=a.Z,c=a.c,d;if(!(d=b.applicationId!=c.appId||b.name!=c.displayName)){a:if(d=b.namespaces,b=b.sa(c.namespaces||[]),ka(d)&&ka(b)&&d.length==b.length){for(var c=d.length,e=0;e<c;e++)if(d[e]!==b[e]){d=!1;break a}d=!0}else d=!1;d=!d}d&&(a.Z=new Kb(a.c),
1849 a.h.dispatchEvent(new Lb(a.Z)));Tb(a,a.c.receiver);a.S!=a.c.statusText&&(a.S=a.c.statusText,a.h.dispatchEvent(new Mb(a.S)));break;default:I("Unknown session status "+this.b.c.status)}else I("Received session update event without known session")};
1850 var X=function(a,b,c){b==a.l?"SESSION_START_FAILED"==b&&a.h.dispatchEvent(new Vb(a.b,a.l,c)):(a.l=b,a.b&&(a.b.g=a.l),a.h.dispatchEvent(new Vb(a.b,a.l,c)),Wb(a))},Wb=function(a){var b="NO_DEVICES_AVAILABLE";switch(a.l){case "SESSION_STARTING":case "SESSION_ENDING":b="CONNECTING";break;case "SESSION_STARTED":case "SESSION_RESUMED":b="CONNECTED";break;case "NO_SESSION":case "SESSION_ENDED":case "SESSION_START_FAILED":b=a.va?"NOT_CONNECTED":"NO_DEVICES_AVAILABLE";break;default:I("Unexpected session state: "+
1851 a.l)}b!==a.L&&(a.L=b,a.h.dispatchEvent(new Ub(b)))};W.na=void 0;W.M=function(){return W.na?W.na:W.na=new W};W.getInstance=W.M;var Y=function(){return HTMLButtonElement.call(this)||this};g(Y,HTMLButtonElement);Y.prototype.createdCallback=function(){this.createShadowRoot&&(this.createShadowRoot().innerHTML='<style>.connected {fill:var(--connected-color,#4285F4);}.disconnected {fill:var(--disconnected-color,#7D7D7D);}.hidden {opacity:0;}</style><svg id "svg" x="0px" y="0px" width="100%" height="100%" viewBox="0 0 24 24"><g><path id="arch0" class="disconnected" d="M1,18 L1,21 L4,21 C4,19.34 2.66,18 1,18 L1,18 Z"/><path id="arch1" class="disconnected" d="M1,14 L1,16 C3.76,16 6,18.24 6,21 L8,21 C8,17.13 4.87,14 1,14 L1,14 Z"/><path id="arch2" class="disconnected" d="M1,10 L1,12 C5.97,12 10,16.03 10,21 L12,21 C12,14.92 7.07,10 1,10 L1,10 Z"/><path id="box" class="disconnected" d="M21,3 L3,3 C1.9,3 1,3.9 1,5 L1,8 L3,8 L3,5 L21,5 L21,19 L14,19 L14,21 L21,21 C22.1,21 23,20.1 23,19 L23,5 C23,3.9 22.1,3 21,3 L21,3 Z"/><path id="boxfill" class="hidden" d="M5,7 L5,8.63 C8,8.63 13.37,14 13.37,17 L19,17 L19,7 Z"/></g></svg>')};
1852 Y.prototype.attachedCallback=function(){if(this.shadowRoot){this.fa=W.M();this.Ja=this.ub.bind(this);this.ca=[];for(var a=0;3>a;a++)this.ca.push(this.shadowRoot.getElementById("arch"+a));this.Ua=this.shadowRoot.getElementById("box");this.Va=this.shadowRoot.getElementById("boxfill");this.ua=0;this.H=null;this.Ya=window.getComputedStyle(this,null).display;this.g=this.fa.L;Xb(this);this.addEventListener("click",Yb);this.fa.addEventListener("caststatechanged",this.Ja)}};
1853 Y.prototype.detachedCallback=function(){this.fa.removeEventListener("caststatechanged",this.Ja);null!==this.H&&(window.clearTimeout(this.H),this.H=null)};var Yb=function(){W.M().requestSession()};Y.prototype.ub=function(a){this.g=a.castState;Xb(this)};var Xb=function(a){if("NO_DEVICES_AVAILABLE"==a.g)a.style.display="none";else switch(a.style.display=a.Ya,a.g){case "NOT_CONNECTED":Zb(a,!1,"hidden");break;case "CONNECTING":Zb(a,!1,"hidden");a.H||a.Ba();break;case "CONNECTED":Zb(a,!0,"connected")}};
1854 Y.prototype.Ba=function(){this.H=null;if("CONNECTING"==this.g){for(var a=0;3>a;a++)$b(this.ca[a],a==this.ua);this.ua=(this.ua+1)%3;this.H=window.setTimeout(this.Ba.bind(this),300)}};var Zb=function(a,b,c){for(var d=ia(a.ca),e=d.next();!e.done;e=d.next())$b(e.value,b);$b(a.Ua,b);a.Va.setAttribute("class",c)},$b=function(a,b){a.setAttribute("class",b?"connected":"disconnected")};
1855 (function(){var a=function(){document.registerElement("google-cast-button",{prototype:Y.prototype,extends:"button"})};if(document.registerElement)a();else{window.addEventListener("WebComponentsReady",a);Eb();for(var a=ia(document.querySelectorAll("button[is=google-cast-button]")),b=a.next();!b.done;b=a.next())b.value.onclick=Yb}})();t("cast.framework.RemotePlayer",function(){this.isMediaLoaded=this.isConnected=!1;this.currentTime=this.duration=0;this.volumeLevel=1;this.canControlVolume=!0;this.canSeek=this.canPause=this.isMuted=this.isPaused=!1;this.displayStatus=this.title=this.statusText=this.displayName="";this.controller=this.savedPlayerState=this.playerState=this.imageUrl=this.mediaInfo=null});var ac=function(a,b,c){this.type=a;this.field=b;this.value=c};g(ac,T);t("cast.framework.RemotePlayerChangedEvent",ac);var Z=function(a){var b=new U;S.call(this,bc(a,b));this.h=b;a=W.M();a.addEventListener("sessionstatechanged",this.Db.bind(this));(a=a.b)?Cb(this,a.c):this.u()};g(Z,S);t("cast.framework.RemotePlayerController",Z);var bc=function(a,b){return new window.Proxy(a,{set:function(a,d,e){if(e===a[d])return!0;a[d]=e;b.dispatchEvent(new ac(d+"Changed",d,e));b.dispatchEvent(new ac("anyChanged",d,e));return!0}})};Z.prototype.addEventListener=function(a,b){this.h.addEventListener(a,b)};
1856 Z.prototype.addEventListener=Z.prototype.addEventListener;Z.prototype.removeEventListener=function(a,b){this.h.removeEventListener(a,b)};Z.prototype.removeEventListener=Z.prototype.removeEventListener;Z.prototype.Db=function(a){switch(a.sessionState){case "SESSION_STARTED":case "SESSION_RESUMED":this.a.isConnected=!0;var b=a.session&&a.session.c;b&&(Cb(this,b),a.session.addEventListener("mediasession",this.Ga.bind(this)))}};
1857 Z.prototype.u=function(a){var b=W.M().b;b?this.a.savedPlayerState=null:this.a.isConnected&&(this.a.savedPlayerState={mediaInfo:this.a.mediaInfo,currentTime:this.a.currentTime,isPaused:this.a.isPaused});S.prototype.u.call(this,a);this.a.isConnected=!!b;this.a.statusText=b&&b.S||"";a=b&&b.qa;this.a.playerState=a&&a.playerState||null};
1858 Z.prototype.T=function(a){S.prototype.T.call(this,a);var b=(this.a.mediaInfo=a)&&a.metadata;a=null;var c="";b&&(c=b.title||"",(b=b.images)&&0<b.length&&(a=b[0].url));this.a.title=c;this.a.imageUrl=a};Z.prototype.ta=function(){S.prototype.ta.call(this)};Z.prototype.playOrPause=Z.prototype.ta;Z.prototype.stop=function(){S.prototype.stop.call(this)};Z.prototype.stop=Z.prototype.stop;Z.prototype.seek=function(){S.prototype.seek.call(this)};Z.prototype.seek=Z.prototype.seek;Z.prototype.ra=function(){S.prototype.ra.call(this)};
1859 Z.prototype.muteOrUnmute=Z.prototype.ra;Z.prototype.ya=function(){S.prototype.ya.call(this)};Z.prototype.setVolumeLevel=Z.prototype.ya;Z.prototype.ja=function(a){return S.prototype.ja.call(this,a)};Z.prototype.getFormattedTime=Z.prototype.ja;Z.prototype.ka=function(a,b){return S.prototype.ka.call(this,a,b)};Z.prototype.getSeekPosition=Z.prototype.ka;Z.prototype.la=function(a,b){return S.prototype.la.call(this,a,b)};Z.prototype.getSeekTime=Z.prototype.la;
1860
1861 }).call(window);
1862(function(window) {
1863 'use strict';
1864
1865 var bufferingSvg = '' +
1866 '<path class="mhp1138_normal" fill="#F6921E" d="M164,661c-53-59-87-136-90-220H0c4,105,45,200,112,272L164,661z"></path>' +
1867 '<path class="mhp1138_normal" fill="#F6921E" d="M186,167c58-54,135-89,220-93V0C301,5,205,48,134,115L186,167z"></path>' +
1868 '<path class="mhp1138_normal" fill="#F6921E" d="M74,410c4-85,37-161,90-220l-52-52C45,209,4,305,0,410H74z"></path>' +
1869 '<path class="mhp1138_faded1" fill="#C16425" d="M437,0v74c86,3,164,37,224,90l52-52C640,45,543,3,437,0z"></path>' +
1870 '<path class="mhp1138_faded3" fill="#442006" d="M776,440c-4,86-39,164-94,224l52,52C803,644,846,547,850,440H776z"></path>' +
1871 '<path class="mhp1138_faded2" fill="#A04F12" d="M683,186c55,59,90,137,94,224H850c-4-107-47-203-115-276L683,186z"></path>' +
1872 '<path class="mhp1138_normal" fill="#F6921E" d="M406,776c-85-5-162-39-220-93l-52,52c72,68,167,110,272,115V776z"></path>' +
1873 '<path class="mhp1138_normal" fill="#F6921E" d="M661,686c-60,54-138,87-224,90V850c106-3,203-45,276-112L661,686z"></path>';
1874
1875 var markup = {
1876 controlBar: {
1877 front: {
1878 // all tooltips stored in declarative way as regular HTML 'title' attrs,
1879 // which appear as system tooltips if no JS code applied
1880 playPause: '.btn.play.icon.icon-play[title="%PLAY%"] + .btn.pause.icon.icon-pause[title="%PAUSE%"] + .btn.replay.icon.icon-replay[title="%REPLAY%"]',
1881 time: 'span.elapsed[html=00:00] + span.sep[html=/] + span.total[html=00:00]',
1882 sound: {
1883 volume: '.btn.volume-low.icon.icon-volume-low[title="%MUTE%"] + .btn.volume-full.icon.icon-volume-full[title="%MUTE%"] + .btn.volume-mute.icon.icon-volume-mute[title="%UNMUTE%"]',
1884 'volumeSlider.hidden': { // volumeSlider should be hidden on init. Doing so by markup, no JS-code needed
1885 volumeBar: {
1886 front: '.handle',
1887 background: null,
1888 extraZone: '.left + .right'
1889 }
1890 }
1891 },
1892 fullscreen: '.btn.fullscreenOff.icon.icon-fullscreen[title="%FULL_SCREEN%"] + .btn.fullscreenOn.icon.icon-fullscreen-exit[title="%EXIT_FULL_SCREEN%"]',
1893 chromecast: 'button.chromecastBtn[is="google-cast-button"][title="%CHROMECAST%"]',
1894 logo: null,
1895 cinema: '.btn.normal.icon.icon-size-large[title="%LARGE_PLAYER%"] + .btn.large.icon.icon-size-medium[title="%SMALL_PLAYER%"] ',
1896 options: '.btn.icon.icon-quality[title="%QUALITY%"] + .optionsPopup > div.switchers + ul',
1897 cover: null,
1898 leftVolumeBarCover: null,
1899 rightVolumeBarCover: null
1900 },
1901 background: null,
1902 seekBar: {
1903 progressPadding: {
1904 // background: null,
1905 //buffer: null,
1906 progressOverflow: {
1907 background: null,
1908 //buffer: null,
1909 progress: null
1910 },
1911 handle: null
1912 }
1913 }
1914 },
1915 eventCatcher: null,
1916 playerStateIcon: {
1917 play: '.icon.icon-play',
1918 buffering: 'svg[viewBox=0 0 850 850] > g[html=' + bufferingSvg + ']',
1919 background: null
1920 },
1921 preRollTitle: '[html="%ADVERTISEMENT_TITLE%"]',
1922 preRollSkipButton: {
1923 content: null
1924 },
1925 share: '.btn.icon.icon-share-round[title="%SHARE%"][tooltipPosition=left]',
1926 'thumbnails.hidden': {
1927 box: {
1928 actionTagTitle: null,
1929 sprite: 'img.image + .shadow',
1930 selectedTime: null
1931 },
1932 arrow: null
1933 },
1934 'tooltip.hidden': {
1935 title: null,
1936 arrow: null
1937 },
1938 videoErrorMessage: {
1939 centered: '.span.icon.icon-error + p'
1940 },
1941 videoPoster: null,
1942 topBar: {
1943 content: {
1944 title: 'span'
1945 },
1946 background: null
1947 },
1948 contextMenu: {
1949 content: {
1950 'copyEmbed[html="%COPY_EMBED_CODE%"]': null,
1951 'copyUrlVideoTime[html="%COPY_URL_CURRENT_TIME%"]': null,
1952 'copyUrlVideo[html="%COPY_URL%"]': null,
1953 'about[html="%ABOUT%"]': null
1954 }
1955 },
1956 versionsInfo: {
1957 copyCloseDiv: '.hideVersionMenu + .copyMenu .btn.icon.icon-copy',
1958 playerVersions: '.playerVersionContainer + .streamingInfoContainer + .prerollInfoContainer'
1959
1960 }
1961 };
1962
1963 window.MHP1138 = window.MHP1138 || {};
1964 window.MHP1138.markup = markup;
1965})(window);
1966(function() {'use strict';if(!window.PresentationRequest)return;var e,aa=function(a,b){function c(){}c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a;for(var d in b)if(Object.defineProperties){var f=Object.getOwnPropertyDescriptor(b,d);f&&Object.defineProperty(a,d,f)}else a[d]=b[d]},ba="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},g="undefined"!=typeof window&&
1967 window===this?this:"undefined"!=typeof global&&null!=global?global:this,ca=function(){ca=function(){};g.Symbol||(g.Symbol=da)},ea=0,da=function(a){return"jscomp_symbol_"+(a||"")+ea++},l=function(){ca();var a=g.Symbol.iterator;a||(a=g.Symbol.iterator=g.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&ba(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return fa(this)}});l=function(){}},fa=function(a){var b=0;return ga(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})},
1968 ga=function(a){l();a={next:a};a[g.Symbol.iterator]=function(){return this};return a},n=this,p=function(a,b,c){a=a.split(".");c=c||n;a[0]in c||!c.execScript||c.execScript("var "+a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?c=c[d]?c[d]:c[d]={}:c[d]=b},ia=function(){},q=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==
1969 c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},r=function(a){var b=q(a);return"array"==b||"object"==b&&"number"==typeof a.length},t=function(a){return"string"==
1970 typeof a},ja="closure_uid_"+(1E9*Math.random()>>>0),ka=0,la=function(a,b,c){return a.call.apply(a.bind,arguments)},ma=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}},u=function(a,b,c){u=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?la:ma;
1971 return u.apply(null,arguments)},na=function(a,b){function c(){}c.prototype=b.prototype;a.ge=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.ce=function(a,c,h){for(var d=Array(arguments.length-2),f=2;f<arguments.length;f++)d[f-2]=arguments[f];return b.prototype[c].apply(a,d)}};var chrome=chrome||window.chrome||{};chrome.cast=chrome.cast||{};chrome.cast.media=chrome.cast.media||{};chrome.cast.VERSION=[1,2];p("chrome.cast.VERSION",chrome.cast.VERSION,void 0);chrome.cast.ae=!0;p("chrome.cast.usingPresentationApi",chrome.cast.ae,void 0);chrome.cast.Error=function(a,b,c){this.code=a;this.description=b||null;this.details=c||null};p("chrome.cast.Error",chrome.cast.Error,void 0);chrome.cast.uc=function(a){this.platform=a;this.packageId=this.url=null};p("chrome.cast.SenderApplication",chrome.cast.uc,void 0);chrome.cast.Image=function(a){this.url=a;this.width=this.height=null};
1972 p("chrome.cast.Image",chrome.cast.Image,void 0);chrome.cast.Volume=function(a,b){this.level=void 0!==a?a:null;this.muted=void 0!==b?b:null};p("chrome.cast.Volume",chrome.cast.Volume,void 0);var oa=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},pa=/&/g,qa=/</g,ra=/>/g,sa=/"/g,ta=/'/g,ua=/\x00/g,va=/[\x00&<>"']/,xa=function(a,b){var c={"&":"&","<":"<",">":">",""":'"'},d;d=b?b.createElement("div"):n.document.createElement("div");return a.replace(wa,function(a,b){var f=c[a];if(f)return f;"#"==b.charAt(0)&&(b=Number("0"+b.substr(1)),isNaN(b)||(f=String.fromCharCode(b)));f||(d.innerHTML=a+" ",f=d.firstChild.nodeValue.slice(0,
1973 -1));return c[a]=f})},ya=function(a){return a.replace(/&([^;]+);/g,function(a,c){switch(c){case "amp":return"&";case "lt":return"<";case "gt":return">";case "quot":return'"';default:return"#"!=c.charAt(0)||(c=Number("0"+c.substr(1)),isNaN(c))?a:String.fromCharCode(c)}})},wa=/&([^;\s<&]+);?/g,w=function(a,b){return a<b?-1:a>b?1:0};chrome.cast.bb={CUSTOM_CONTROLLER_SCOPED:"custom_controller_scoped",TAB_AND_ORIGIN_SCOPED:"tab_and_origin_scoped",ORIGIN_SCOPED:"origin_scoped",PAGE_SCOPED:"page_scoped"};p("chrome.cast.AutoJoinPolicy",chrome.cast.bb,void 0);chrome.cast.cb={CREATE_SESSION:"create_session",CAST_THIS_TAB:"cast_this_tab"};p("chrome.cast.DefaultActionPolicy",chrome.cast.cb,void 0);chrome.cast.Ca={VIDEO_OUT:"video_out",AUDIO_OUT:"audio_out",VIDEO_IN:"video_in",AUDIO_IN:"audio_in",MULTIZONE_GROUP:"multizone_group"};
1974 p("chrome.cast.Capability",chrome.cast.Ca,void 0);chrome.cast.u={CANCEL:"cancel",TIMEOUT:"timeout",API_NOT_INITIALIZED:"api_not_initialized",INVALID_PARAMETER:"invalid_parameter",EXTENSION_NOT_COMPATIBLE:"extension_not_compatible",EXTENSION_MISSING:"extension_missing",RECEIVER_UNAVAILABLE:"receiver_unavailable",SESSION_ERROR:"session_error",CHANNEL_ERROR:"channel_error",LOAD_MEDIA_FAILED:"load_media_failed"};p("chrome.cast.ErrorCode",chrome.cast.u,void 0);chrome.cast.ha={AVAILABLE:"available",UNAVAILABLE:"unavailable"};
1975 p("chrome.cast.ReceiverAvailability",chrome.cast.ha,void 0);chrome.cast.vc={CHROME:"chrome",IOS:"ios",ANDROID:"android"};p("chrome.cast.SenderPlatform",chrome.cast.vc,void 0);chrome.cast.mb={CAST:"cast",DIAL:"dial",HANGOUT:"hangout",CUSTOM:"custom"};p("chrome.cast.ReceiverType",chrome.cast.mb,void 0);chrome.cast.Zb={RUNNING:"running",STOPPED:"stopped",ERROR:"error"};p("chrome.cast.DialAppState",chrome.cast.Zb,void 0);chrome.cast.qc={CAST:"cast",STOP:"stop"};
1976 p("chrome.cast.ReceiverAction",chrome.cast.qc,void 0);chrome.cast.U={CONNECTED:"connected",DISCONNECTED:"disconnected",STOPPED:"stopped"};p("chrome.cast.SessionStatus",chrome.cast.U,void 0);chrome.cast.Xb=function(a,b,c,d,f){this.sessionRequest=a;this.sessionListener=b;this.receiverListener=c;this.autoJoinPolicy=d||chrome.cast.bb.TAB_AND_ORIGIN_SCOPED;this.defaultActionPolicy=f||chrome.cast.cb.CREATE_SESSION;this.customDialLaunchCallback=null;this.invisibleSender=!1;this.additionalSessionRequests=[]};p("chrome.cast.ApiConfig",chrome.cast.Xb,void 0);chrome.cast.bc=function(a,b){this.appName=a;this.launchParameter=b||null};p("chrome.cast.DialRequest",chrome.cast.bc,void 0);
1977 chrome.cast.$b=function(a,b,c){this.receiver=a;this.appState=b;this.extraData=c||null};p("chrome.cast.DialLaunchData",chrome.cast.$b,void 0);chrome.cast.ac=function(a,b){this.doLaunch=a;this.launchParameter=b||null};p("chrome.cast.DialLaunchResponse",chrome.cast.ac,void 0);chrome.cast.wc=function(a,b,c){this.appId=a;this.capabilities="array"==q(b)?b:[chrome.cast.Ca.VIDEO_OUT,chrome.cast.Ca.AUDIO_OUT];this.requestSessionTimeout=c||chrome.cast.timeout.requestSession;this.dialRequest=this.language=null};
1978 p("chrome.cast.SessionRequest",chrome.cast.wc,void 0);
1979 chrome.cast.pc=function(a,b,c,d){this.label=a;a=b;va.test(a)&&(-1!=a.indexOf("&")&&(a=a.replace(pa,"&")),-1!=a.indexOf("<")&&(a=a.replace(qa,"<")),-1!=a.indexOf(">")&&(a=a.replace(ra,">")),-1!=a.indexOf('"')&&(a=a.replace(sa,""")),-1!=a.indexOf("'")&&(a=a.replace(ta,"'")),-1!=a.indexOf("\x00")&&(a=a.replace(ua,"�")));this.friendlyName=a;this.capabilities=c||[];this.volume=d||null;this.receiverType=chrome.cast.mb.CAST;this.displayStatus=this.isActiveInput=null};
1980 p("chrome.cast.Receiver",chrome.cast.pc,void 0);chrome.cast.rc=function(a,b){this.statusText=a;this.appImages=b;this.showStop=null};p("chrome.cast.ReceiverDisplayStatus",chrome.cast.rc,void 0);chrome.cast.pb=function(){this.requestSession=6E4;this.sendCustomMessage=this.setReceiverVolume=this.stopSession=this.leaveSession=3E3};p("chrome.cast.Timeout",chrome.cast.pb,void 0);chrome.cast.timeout=new chrome.cast.pb;p("chrome.cast.timeout",chrome.cast.timeout,void 0);chrome.cast.Wb="auto-join";
1981 chrome.cast.kc="cast-session_";chrome.cast.media.gc={PAUSE:"pause",SEEK:"seek",STREAM_VOLUME:"stream_volume",STREAM_MUTE:"stream_mute"};p("chrome.cast.media.MediaCommand",chrome.cast.media.gc,void 0);chrome.cast.media.s={GENERIC:0,MOVIE:1,TV_SHOW:2,MUSIC_TRACK:3,PHOTO:4};p("chrome.cast.media.MetadataType",chrome.cast.media.s,void 0);chrome.cast.media.T={IDLE:"IDLE",PLAYING:"PLAYING",PAUSED:"PAUSED",BUFFERING:"BUFFERING"};p("chrome.cast.media.PlayerState",chrome.cast.media.T,void 0);
1982 chrome.cast.media.Da={OFF:"REPEAT_OFF",ALL:"REPEAT_ALL",SINGLE:"REPEAT_SINGLE",ALL_AND_SHUFFLE:"REPEAT_ALL_AND_SHUFFLE"};p("chrome.cast.media.RepeatMode",chrome.cast.media.Da,void 0);chrome.cast.media.sc={PLAYBACK_START:"PLAYBACK_START",PLAYBACK_PAUSE:"PLAYBACK_PAUSE"};p("chrome.cast.media.ResumeState",chrome.cast.media.sc,void 0);chrome.cast.media.ob={BUFFERED:"BUFFERED",LIVE:"LIVE",OTHER:"OTHER"};p("chrome.cast.media.StreamType",chrome.cast.media.ob,void 0);
1983 chrome.cast.media.ec={CANCELLED:"CANCELLED",INTERRUPTED:"INTERRUPTED",FINISHED:"FINISHED",ERROR:"ERROR"};p("chrome.cast.media.IdleReason",chrome.cast.media.ec,void 0);chrome.cast.media.Ec={TEXT:"TEXT",AUDIO:"AUDIO",VIDEO:"VIDEO"};p("chrome.cast.media.TrackType",chrome.cast.media.Ec,void 0);chrome.cast.media.Bc={SUBTITLES:"SUBTITLES",CAPTIONS:"CAPTIONS",DESCRIPTIONS:"DESCRIPTIONS",CHAPTERS:"CHAPTERS",METADATA:"METADATA"};p("chrome.cast.media.TextTrackType",chrome.cast.media.Bc,void 0);
1984 chrome.cast.media.xc={NONE:"NONE",OUTLINE:"OUTLINE",DROP_SHADOW:"DROP_SHADOW",RAISED:"RAISED",DEPRESSED:"DEPRESSED"};p("chrome.cast.media.TextTrackEdgeType",chrome.cast.media.xc,void 0);chrome.cast.media.Cc={NONE:"NONE",NORMAL:"NORMAL",ROUNDED_CORNERS:"ROUNDED_CORNERS"};p("chrome.cast.media.TextTrackWindowType",chrome.cast.media.Cc,void 0);
1985 chrome.cast.media.yc={SANS_SERIF:"SANS_SERIF",MONOSPACED_SANS_SERIF:"MONOSPACED_SANS_SERIF",SERIF:"SERIF",MONOSPACED_SERIF:"MONOSPACED_SERIF",CASUAL:"CASUAL",CURSIVE:"CURSIVE",SMALL_CAPITALS:"SMALL_CAPITALS"};p("chrome.cast.media.TextTrackFontGenericFamily",chrome.cast.media.yc,void 0);chrome.cast.media.zc={NORMAL:"NORMAL",BOLD:"BOLD",BOLD_ITALIC:"BOLD_ITALIC",ITALIC:"ITALIC"};p("chrome.cast.media.TextTrackFontStyle",chrome.cast.media.zc,void 0);chrome.cast.media.eb=function(){this.customData=null};p("chrome.cast.media.GetStatusRequest",chrome.cast.media.eb,void 0);chrome.cast.media.fb=function(){this.customData=null};p("chrome.cast.media.PauseRequest",chrome.cast.media.fb,void 0);chrome.cast.media.gb=function(){this.customData=null};p("chrome.cast.media.PlayRequest",chrome.cast.media.gb,void 0);chrome.cast.media.tc=function(){this.customData=this.resumeState=this.currentTime=null};p("chrome.cast.media.SeekRequest",chrome.cast.media.tc,void 0);
1986 chrome.cast.media.nb=function(){this.customData=null};p("chrome.cast.media.StopRequest",chrome.cast.media.nb,void 0);chrome.cast.media.Gc=function(a){this.volume=a;this.customData=null};p("chrome.cast.media.VolumeRequest",chrome.cast.media.Gc,void 0);chrome.cast.media.fc=function(a){this.type="LOAD";this.requestId=0;this.sessionId=null;this.media=a;this.activeTrackIds=null;this.autoplay=!0;this.customData=this.currentTime=null};p("chrome.cast.media.LoadRequest",chrome.cast.media.fc,void 0);
1987 chrome.cast.media.mc=function(a){this.type="PRECACHE";this.requestId=0;this.data=a};chrome.cast.media.cc=function(a,b){this.requestId=0;this.activeTrackIds=a||null;this.textTrackStyle=b||null};p("chrome.cast.media.EditTracksInfoRequest",chrome.cast.media.cc,void 0);chrome.cast.media.dc=function(){this.metadataType=this.type=chrome.cast.media.s.GENERIC;this.releaseDate=this.releaseYear=this.images=this.subtitle=this.title=null};p("chrome.cast.media.GenericMediaMetadata",chrome.cast.media.dc,void 0);
1988 chrome.cast.media.ic=function(){this.metadataType=this.type=chrome.cast.media.s.MOVIE;this.releaseDate=this.releaseYear=this.images=this.subtitle=this.studio=this.title=null};p("chrome.cast.media.MovieMediaMetadata",chrome.cast.media.ic,void 0);chrome.cast.media.Fc=function(){this.metadataType=this.type=chrome.cast.media.s.TV_SHOW;this.originalAirdate=this.releaseYear=this.images=this.episode=this.episodeNumber=this.season=this.seasonNumber=this.episodeTitle=this.title=this.seriesTitle=null};
1989 p("chrome.cast.media.TvShowMediaMetadata",chrome.cast.media.Fc,void 0);chrome.cast.media.jc=function(){this.metadataType=this.type=chrome.cast.media.s.MUSIC_TRACK;this.releaseDate=this.releaseYear=this.images=this.discNumber=this.trackNumber=this.artistName=this.songName=this.composer=this.artist=this.albumArtist=this.title=this.albumName=null};p("chrome.cast.media.MusicTrackMediaMetadata",chrome.cast.media.jc,void 0);
1990 chrome.cast.media.lc=function(){this.metadataType=this.type=chrome.cast.media.s.PHOTO;this.creationDateTime=this.height=this.width=this.longitude=this.latitude=this.images=this.location=this.artist=this.title=null};p("chrome.cast.media.PhotoMediaMetadata",chrome.cast.media.lc,void 0);chrome.cast.media.hc=function(a,b){this.contentId=a;this.streamType=chrome.cast.media.ob.BUFFERED;this.contentType=b;this.customData=this.textTrackStyle=this.tracks=this.duration=this.metadata=null};
1991 p("chrome.cast.media.MediaInfo",chrome.cast.media.hc,void 0);chrome.cast.media.ib=function(a){this.itemId=null;this.media=a;this.autoplay=!0;this.startTime=0;this.playbackDuration=null;this.preloadTime=0;this.customData=this.activeTrackIds=null};p("chrome.cast.media.QueueItem",chrome.cast.media.ib,void 0);chrome.cast.media.Yb="CC1AD845";p("chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID",chrome.cast.media.Yb,void 0);chrome.cast.media.timeout={};
1992 p("chrome.cast.media.timeout",chrome.cast.media.timeout,void 0);chrome.cast.media.timeout.load=0;chrome.cast.media.timeout.load=chrome.cast.media.timeout.load;chrome.cast.media.timeout.ma=0;chrome.cast.media.timeout.getStatus=chrome.cast.media.timeout.ma;chrome.cast.media.timeout.play=0;chrome.cast.media.timeout.play=chrome.cast.media.timeout.play;chrome.cast.media.timeout.pause=0;chrome.cast.media.timeout.pause=chrome.cast.media.timeout.pause;chrome.cast.media.timeout.seek=0;
1993 chrome.cast.media.timeout.seek=chrome.cast.media.timeout.seek;chrome.cast.media.timeout.stop=0;chrome.cast.media.timeout.stop=chrome.cast.media.timeout.stop;chrome.cast.media.timeout.Ba=0;chrome.cast.media.timeout.setVolume=chrome.cast.media.timeout.Ba;chrome.cast.media.timeout.ka=0;chrome.cast.media.timeout.editTracksInfo=chrome.cast.media.timeout.ka;chrome.cast.media.timeout.o=0;chrome.cast.media.timeout.queue=chrome.cast.media.timeout.o;
1994 chrome.cast.media.Dc=function(a,b){this.trackId=a;this.trackContentType=this.trackContentId=null;this.type=b;this.customData=this.subtype=this.language=this.name=null};p("chrome.cast.media.Track",chrome.cast.media.Dc,void 0);chrome.cast.media.Ac=function(){this.customData=this.fontStyle=this.fontGenericFamily=this.fontFamily=this.fontScale=this.windowRoundedCornerRadius=this.windowColor=this.windowType=this.edgeColor=this.edgeType=this.backgroundColor=this.foregroundColor=null};
1995 p("chrome.cast.media.TextTrackStyle",chrome.cast.media.Ac,void 0);chrome.cast.media.nc=function(a){this.type="QUEUE_LOAD";this.sessionId=this.requestId=null;this.items=a;this.startIndex=0;this.repeatMode=chrome.cast.media.Da.OFF;this.customData=null};p("chrome.cast.media.QueueLoadRequest",chrome.cast.media.nc,void 0);chrome.cast.media.hb=function(a){this.type="QUEUE_INSERT";this.sessionId=this.requestId=null;this.items=a;this.customData=this.insertBefore=null};
1996 p("chrome.cast.media.QueueInsertItemsRequest",chrome.cast.media.hb,void 0);chrome.cast.media.oc=function(a){this.type="QUEUE_UPDATE";this.sessionId=this.requestId=null;this.items=a;this.customData=null};p("chrome.cast.media.QueueUpdateItemsRequest",chrome.cast.media.oc,void 0);chrome.cast.media.ga=function(){this.type="QUEUE_UPDATE";this.customData=this.jump=this.currentItemId=this.sessionId=this.requestId=null};p("chrome.cast.media.QueueJumpRequest",chrome.cast.media.ga,void 0);
1997 chrome.cast.media.lb=function(){this.type="QUEUE_UPDATE";this.customData=this.repeatMode=this.sessionId=this.requestId=null};p("chrome.cast.media.QueueSetPropertiesRequest",chrome.cast.media.lb,void 0);chrome.cast.media.jb=function(a){this.type="QUEUE_REMOVE";this.sessionId=this.requestId=null;this.itemIds=a;this.customData=null};p("chrome.cast.media.QueueRemoveItemsRequest",chrome.cast.media.jb,void 0);
1998 chrome.cast.media.kb=function(a){this.type="QUEUE_REORDER";this.sessionId=this.requestId=null;this.itemIds=a;this.customData=this.insertBefore=null};p("chrome.cast.media.QueueReorderItemsRequest",chrome.cast.media.kb,void 0);var x=Array.prototype.forEach?function(a,b,c){Array.prototype.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,f=t(a)?a.split(""):a,h=0;h<d;h++)h in f&&b.call(c,f[h],h,a)},za=function(a,b,c){for(var d=a.length,f=t(a)?a.split(""):a,h=0;h<d;h++)if(h in f&&b.call(c,f[h],h,a))return h;return-1},Aa=function(a){return Array.prototype.concat.apply(Array.prototype,arguments)},Ba=function(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]};chrome.cast.media.a=function(a,b){this.sessionId=a;this.mediaSessionId=b;this.media=null;this.playbackRate=1;this.playerState=chrome.cast.media.T.IDLE;this.currentTime=0;this.Pa=-1;this.supportedMediaCommands=[];this.volume=new chrome.cast.Volume;this.items=this.preloadedItemId=this.loadingItemId=this.currentItemId=this.customData=this.activeTrackIds=this.idleReason=null;this.repeatMode=chrome.cast.media.Da.OFF;this.na=!1;this.da=[]};p("chrome.cast.media.Media",chrome.cast.media.a,void 0);
1999 chrome.cast.media.a.prototype.ma=function(a,b,c){a||(a=new chrome.cast.media.eb);y.i(this,"MEDIA_GET_STATUS",a,b,c,chrome.cast.media.timeout.ma)};chrome.cast.media.a.prototype.getStatus=chrome.cast.media.a.prototype.ma;chrome.cast.media.a.prototype.play=function(a,b,c){this.Gb(y,a,b,c)};chrome.cast.media.a.prototype.play=chrome.cast.media.a.prototype.play;chrome.cast.media.a.prototype.Gb=function(a,b,c,d){b||(b=new chrome.cast.media.gb);a.i(this,"PLAY",b,c,d,chrome.cast.media.timeout.play)};
2000 chrome.cast.media.a.prototype.playWithContext=chrome.cast.media.a.prototype.Gb;chrome.cast.media.a.prototype.pause=function(a,b,c){this.Fb(y,a,b,c)};chrome.cast.media.a.prototype.pause=chrome.cast.media.a.prototype.pause;chrome.cast.media.a.prototype.Fb=function(a,b,c,d){b||(b=new chrome.cast.media.fb);a.i(this,"PAUSE",b,c,d,chrome.cast.media.timeout.pause)};chrome.cast.media.a.prototype.pauseWithContext=chrome.cast.media.a.prototype.Fb;
2001 chrome.cast.media.a.prototype.seek=function(a,b,c){y.i(this,"SEEK",a,b,c,chrome.cast.media.timeout.seek)};chrome.cast.media.a.prototype.seek=chrome.cast.media.a.prototype.seek;chrome.cast.media.a.prototype.stop=function(a,b,c){a||(a=new chrome.cast.media.nb);y.i(this,"STOP_MEDIA",a,b,c,chrome.cast.media.timeout.stop)};chrome.cast.media.a.prototype.stop=chrome.cast.media.a.prototype.stop;chrome.cast.media.a.prototype.Ba=function(a,b,c){y.i(this,"MEDIA_SET_VOLUME",a,b,c,chrome.cast.media.timeout.Ba)};
2002 chrome.cast.media.a.prototype.setVolume=chrome.cast.media.a.prototype.Ba;chrome.cast.media.a.prototype.ka=function(a,b,c){y.i(this,"EDIT_TRACKS_INFO",a,b,c,chrome.cast.media.timeout.ka)};chrome.cast.media.a.prototype.editTracksInfo=chrome.cast.media.a.prototype.ka;chrome.cast.media.a.prototype.Ad=function(a,b,c){y.i(this,"QUEUE_INSERT",a,b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueInsertItems=chrome.cast.media.a.prototype.Ad;
2003 chrome.cast.media.a.prototype.zd=function(a,b,c){y.i(this,"QUEUE_INSERT",new chrome.cast.media.hb([a]),b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueAppendItem=chrome.cast.media.a.prototype.zd;chrome.cast.media.a.prototype.Kd=function(a,b,c){y.i(this,"QUEUE_UPDATE",a,b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueUpdateItems=chrome.cast.media.a.prototype.Kd;
2004 chrome.cast.media.a.prototype.Fd=function(a,b){var c=new chrome.cast.media.ga;c.jump=-1;y.i(this,"QUEUE_UPDATE",c,a,b,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queuePrev=chrome.cast.media.a.prototype.Fd;chrome.cast.media.a.prototype.Ed=function(a,b){var c=new chrome.cast.media.ga;c.jump=1;y.i(this,"QUEUE_UPDATE",c,a,b,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueNext=chrome.cast.media.a.prototype.Ed;
2005 chrome.cast.media.a.prototype.Bd=function(a,b,c){if(!(0>this.Na(a))){var d=new chrome.cast.media.ga;d.currentItemId=a;y.i(this,"QUEUE_UPDATE",d,b,c,chrome.cast.media.timeout.o)}};chrome.cast.media.a.prototype.queueJumpToItem=chrome.cast.media.a.prototype.Bd;chrome.cast.media.a.prototype.Jd=function(a,b,c){var d=new chrome.cast.media.lb;d.repeatMode=a;y.i(this,"QUEUE_UPDATE",d,b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueSetRepeatMode=chrome.cast.media.a.prototype.Jd;
2006 chrome.cast.media.a.prototype.Hd=function(a,b,c){y.i(this,"QUEUE_REMOVE",a,b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueRemoveItems=chrome.cast.media.a.prototype.Hd;chrome.cast.media.a.prototype.Gd=function(a,b,c){0>this.Na(a)||y.i(this,"QUEUE_REMOVE",new chrome.cast.media.jb([a]),b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueRemoveItem=chrome.cast.media.a.prototype.Gd;chrome.cast.media.a.prototype.Id=function(a,b,c){y.i(this,"QUEUE_REORDER",a,b,c,chrome.cast.media.timeout.o)};
2007 chrome.cast.media.a.prototype.queueReorderItems=chrome.cast.media.a.prototype.Id;chrome.cast.media.a.prototype.Dd=function(a,b,c,d){var f=this.Na(a);if(!(0>f))if(0>b)d&&d(new chrome.cast.Error(chrome.cast.u.INVALID_PARAMETER));else if(f==b)c&&c();else{var h=null;b=b>f?b+1:b;b<this.items.length&&(h=this.items[b]);a=new chrome.cast.media.kb([a]);a.insertBefore=h?h.itemId:null;y.i(this,"QUEUE_REORDER",a,c,d,chrome.cast.media.timeout.o)}};chrome.cast.media.a.prototype.queueMoveItemToNewIndex=chrome.cast.media.a.prototype.Dd;
2008 chrome.cast.media.a.prototype.Zd=function(a){return-1<this.supportedMediaCommands.indexOf(a)};chrome.cast.media.a.prototype.supportsCommand=chrome.cast.media.a.prototype.Zd;chrome.cast.media.a.prototype.Uc=function(){if(this.playerState==chrome.cast.media.T.PLAYING&&0<=this.Pa){var a=this.currentTime+(Date.now()-this.Pa)/1E3*this.playbackRate;this.media&&null!=this.media.duration&&a>this.media.duration&&(a=this.media.duration);0>a&&(a=0);return a}return this.currentTime};
2009 chrome.cast.media.a.prototype.getEstimatedTime=chrome.cast.media.a.prototype.Uc;chrome.cast.media.a.prototype.Ga=function(a){this.V(y,a)};chrome.cast.media.a.prototype.addUpdateListener=chrome.cast.media.a.prototype.Ga;chrome.cast.media.a.prototype.V=function(a,b){a.Ic(this,b)};chrome.cast.media.a.prototype.addUpdateListenerWithContext=chrome.cast.media.a.prototype.V;chrome.cast.media.a.prototype.Sa=function(a){this.aa(y,a)};chrome.cast.media.a.prototype.removeUpdateListener=chrome.cast.media.a.prototype.Sa;
2010 chrome.cast.media.a.prototype.aa=function(a,b){y.Nd(this,b)};chrome.cast.media.a.prototype.removeUpdateListenerWithContext=chrome.cast.media.a.prototype.aa;chrome.cast.media.a.prototype.Na=function(a){return za(this.items,function(b){return b.itemId==a})};var y=null;var Ca=function(a,b,c){this.sessionId=a;this.namespaceName=b;this.message=c};var Da=function(a,b){this.type="SET_VOLUME";this.requestId=0;this.volume=a;this.expectedVolume=b||null};var Ea=function(a){this.type="STOP";this.requestId=0;this.sessionId=a||null};chrome.cast.b=function(a,b,c,d,f){this.sessionId=a;this.appId=b;this.displayName=c;this.statusText=null;this.appImages=d;this.receiver=f;this.senderApps=[];this.namespaces=[];this.media=[];this.status=chrome.cast.U.CONNECTED;this.transportId=""};p("chrome.cast.Session",chrome.cast.b,void 0);chrome.cast.b.prototype.Wd=function(a,b,c){this.Sb(y,a,b,c)};chrome.cast.b.prototype.setReceiverVolumeLevel=chrome.cast.b.prototype.Wd;
2011 chrome.cast.b.prototype.Sb=function(a,b,c,d){b=new Da(new chrome.cast.Volume(b,null),this.receiver.volume);a.setReceiverVolume(this.sessionId,b,c,d)};chrome.cast.b.prototype.setReceiverVolumeLevelWithContext=chrome.cast.b.prototype.Sb;chrome.cast.b.prototype.Vd=function(a,b,c){this.Rb(y,a,b,c)};chrome.cast.b.prototype.setReceiverMuted=chrome.cast.b.prototype.Vd;
2012 chrome.cast.b.prototype.Rb=function(a,b,c,d){a=new Da(new chrome.cast.Volume(null,b),this.receiver.volume);y.setReceiverVolume(this.sessionId,a,c,d)};chrome.cast.b.prototype.setReceiverMutedWithContext=chrome.cast.b.prototype.Rb;chrome.cast.b.prototype.fd=function(a,b){y.leaveSession(this.sessionId,a,b)};chrome.cast.b.prototype.leave=chrome.cast.b.prototype.fd;chrome.cast.b.prototype.stop=function(a,b){this.Ub(y,a,b)};chrome.cast.b.prototype.stop=chrome.cast.b.prototype.stop;
2013 chrome.cast.b.prototype.Ub=function(a,b,c){a.Nb(new Ea(this.sessionId),b,c,chrome.cast.timeout.stopSession)};chrome.cast.b.prototype.stopWithContext=chrome.cast.b.prototype.Ub;chrome.cast.b.prototype.sendMessage=function(a,b,c,d){this.Pb(y,a,b,c,d)};chrome.cast.b.prototype.sendMessage=chrome.cast.b.prototype.sendMessage;chrome.cast.b.prototype.Pb=function(a,b,c,d,f){a.Rd(new Ca(this.sessionId,b,c),d,f)};chrome.cast.b.prototype.sendMessageWithContext=chrome.cast.b.prototype.Pb;
2014 chrome.cast.b.prototype.Ga=function(a){this.V(y,a)};chrome.cast.b.prototype.addUpdateListener=chrome.cast.b.prototype.Ga;chrome.cast.b.prototype.V=function(a,b){a.Lc(this.sessionId,b)};chrome.cast.b.prototype.addUpdateListenerWithContext=chrome.cast.b.prototype.V;chrome.cast.b.prototype.Sa=function(a){this.aa(y,a)};chrome.cast.b.prototype.removeUpdateListener=chrome.cast.b.prototype.Sa;chrome.cast.b.prototype.aa=function(a,b){a.Qd(this.sessionId,b)};
2015 chrome.cast.b.prototype.removeUpdateListenerWithContext=chrome.cast.b.prototype.aa;chrome.cast.b.prototype.Jc=function(a,b){this.rb(y,a,b)};chrome.cast.b.prototype.addMessageListener=chrome.cast.b.prototype.Jc;chrome.cast.b.prototype.rb=function(a,b,c){a.Hc(this.sessionId,b,c)};chrome.cast.b.prototype.addMessageListenerWithContext=chrome.cast.b.prototype.rb;chrome.cast.b.prototype.Ea=function(a){this.qb(y,a)};chrome.cast.b.prototype.addMediaListener=chrome.cast.b.prototype.Ea;
2016 chrome.cast.b.prototype.qb=function(a,b){a.Ea(this.sessionId,b)};chrome.cast.b.prototype.addMediaListenerWithContext=chrome.cast.b.prototype.qb;chrome.cast.b.prototype.Qa=function(a){this.Ib(y,a)};chrome.cast.b.prototype.removeMediaListener=chrome.cast.b.prototype.Qa;chrome.cast.b.prototype.Ib=function(a,b){a.Qa(this.sessionId,b)};chrome.cast.b.prototype.removeMediaListenerWithContext=chrome.cast.b.prototype.Ib;chrome.cast.b.prototype.Od=function(a,b){this.Jb(y,a,b)};
2017 chrome.cast.b.prototype.removeMessageListener=chrome.cast.b.prototype.Od;chrome.cast.b.prototype.Jb=function(a,b,c){a.Ld(this.sessionId,b,c)};chrome.cast.b.prototype.removeMessageListenerWithContext=chrome.cast.b.prototype.Jb;chrome.cast.b.prototype.hd=function(a,b,c){a.sessionId=this.sessionId;y.Ob(a,"LOAD",b,c)};chrome.cast.b.prototype.loadMedia=chrome.cast.b.prototype.hd;chrome.cast.b.prototype.Cd=function(a,b,c){a.sessionId=this.sessionId;y.Ob(a,"QUEUE_LOAD",b,c)};
2018 chrome.cast.b.prototype.queueLoad=chrome.cast.b.prototype.Cd;var Fa=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b},Ga=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b};var z="StopIteration"in n?n.StopIteration:{message:"StopIteration",stack:""},A=function(){};A.prototype.next=function(){throw z;};A.prototype.v=function(){return this};
2019 var Ha=function(a){if(a instanceof A)return a;if("function"==typeof a.v)return a.v(!1);if(r(a)){var b=0,c=new A;c.next=function(){for(;;){if(b>=a.length)throw z;if(b in a)return a[b++];b++}};return c}throw Error("Not implemented");},B=function(a,b,c){if(r(a))try{x(a,b,c)}catch(d){if(d!==z)throw d;}else{a=Ha(a);try{for(;;)b.call(c,a.next(),void 0,a)}catch(d){if(d!==z)throw d;}}};var C=function(a,b){this.h={};this.g=[];this.fa=this.f=0;var c=arguments.length;if(1<c){if(c%2)throw Error("Uneven number of arguments");for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else a&&this.addAll(a)};e=C.prototype;e.l=function(){this.ia();for(var a=[],b=0;b<this.g.length;b++)a.push(this.h[this.g[b]]);return a};e.B=function(){this.ia();return this.g.concat()};e.M=function(a){return D(this.h,a)};e.clear=function(){this.h={};this.fa=this.f=this.g.length=0};
2020 e.remove=function(a){return D(this.h,a)?(delete this.h[a],this.f--,this.fa++,this.g.length>2*this.f&&this.ia(),!0):!1};e.ia=function(){if(this.f!=this.g.length){for(var a=0,b=0;a<this.g.length;){var c=this.g[a];D(this.h,c)&&(this.g[b++]=c);a++}this.g.length=b}if(this.f!=this.g.length){for(var d={},b=a=0;a<this.g.length;)c=this.g[a],D(d,c)||(this.g[b++]=c,d[c]=1),a++;this.g.length=b}};e.get=function(a,b){return D(this.h,a)?this.h[a]:b};
2021 e.set=function(a,b){D(this.h,a)||(this.f++,this.g.push(a),this.fa++);this.h[a]=b};e.addAll=function(a){var b;a instanceof C?(b=a.B(),a=a.l()):(b=Ga(a),a=Fa(a));for(var c=0;c<b.length;c++)this.set(b[c],a[c])};e.forEach=function(a,b){for(var c=this.B(),d=0;d<c.length;d++){var f=c[d],h=this.get(f);a.call(b,h,f,this)}};e.clone=function(){return new C(this)};
2022 e.v=function(a){this.ia();var b=0,c=this.fa,d=this,f=new A;f.next=function(){if(c!=d.fa)throw Error("The map has changed since the iterator was created");if(b>=d.g.length)throw z;var f=d.g[b++];return a?f:d.h[f]};return f};var D=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var Ia=function(a,b){this.requestId=a;this.$d=b;this.Vb=null};Ia.prototype.Eb=function(){};var E=function(){this.ta=new C};E.prototype.Kc=function(a){var b=this;this.ta.set(a.requestId,a);a.Vb=setTimeout(function(){return b.ud(a)},a.$d)};E.prototype.Kb=function(a){var b=this.ta.get(a);if(!b)return null;clearTimeout(b.Vb);this.ta.remove(a);return b};E.prototype.ud=function(a){this.ta.remove(a.requestId);a.Eb()};var Ja=function(a){this.ld=a},La=function(a){var b=Ka.get(a);b||(b=new Ja(a),Ka.set(a,b));return b};e=Ja.prototype;e.log=function(a,b,c){if(1<=a){"function"==typeof b&&(b=b());var d={fe:this.ld,level:a,time:Date.now(),message:b,de:c};Ma.forEach(function(a){return a(d)})}};e.error=function(a,b){this.log(3,a,b)};e.be=function(a,b){this.log(2,a,b)};e.info=function(a,b){this.log(1,a,b)};e.Bb=function(a,b){this.log(0,a,b)};var Ma=[],Ka=new Map;var F=function(){this.Ka=this.Ka;this.pd=this.pd};F.prototype.Ka=!1;F.prototype.isDisposed=function(){return this.Ka};var Na=function(a,b,c,d){d=d?d(b):b;return Object.prototype.hasOwnProperty.call(a,d)?a[d]:a[d]=c(b)};var G;a:{var Oa=n.navigator;if(Oa){var Pa=Oa.userAgent;if(Pa){G=Pa;break a}}G=""}var H=function(a){return-1!=G.indexOf(a)};var Qa=H("Opera"),I=H("Trident")||H("MSIE"),Ra=H("Edge"),J=H("Gecko")&&!(-1!=G.toLowerCase().indexOf("webkit")&&!H("Edge"))&&!(H("Trident")||H("MSIE"))&&!H("Edge"),K=-1!=G.toLowerCase().indexOf("webkit")&&!H("Edge"),Sa;
2023 a:{var Ta="",Ua=function(){var a=G;if(J)return/rv\:([^\);]+)(\)|;)/.exec(a);if(Ra)return/Edge\/([\d\.]+)/.exec(a);if(I)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(K)return/WebKit\/(\S+)/.exec(a);if(Qa)return/(?:Version)[ \/]?(\S+)/.exec(a)}();Ua&&(Ta=Ua?Ua[1]:"");if(I){var L,Va=n.document;L=Va?Va.documentMode:void 0;if(null!=L&&L>parseFloat(Ta)){Sa=String(L);break a}}Sa=Ta}
2024 var Wa=Sa,Xa={},M=function(a){return Na(Xa,a,function(){for(var b=0,c=oa(String(Wa)).split("."),d=oa(String(a)).split("."),f=Math.max(c.length,d.length),h=0;0==b&&h<f;h++){var k=c[h]||"",m=d[h]||"";do{k=/(\d*)(\D*)(.*)/.exec(k)||["","","",""];m=/(\d*)(\D*)(.*)/.exec(m)||["","","",""];if(0==k[0].length&&0==m[0].length)break;b=w(0==k[1].length?0:parseInt(k[1],10),0==m[1].length?0:parseInt(m[1],10))||w(0==k[2].length,0==m[2].length)||w(k[2],m[2]);k=k[3];m=m[3]}while(0==b)}return 0<=b})};I&&M("9");!K||M("528");J&&M("1.9b")||I&&M("8")||Qa&&M("9.5")||K&&M("528");J&&!M("8")||I&&M("9");var Ya=function(a,b,c){F.call(this);this.gd=null!=c?u(a,c):a;this.ad=b;this.Ia=u(this.vd,this);this.Ha=[]};na(Ya,F);e=Ya.prototype;e.S=!1;e.$=0;e.J=null;e.Sc=function(a){this.Ha=arguments;this.J||this.$?this.S=!0:this.La()};e.stop=function(){this.J&&(n.clearTimeout(this.J),this.J=null,this.S=!1,this.Ha=[])};e.pause=function(){this.$++};e.resume=function(){this.$--;this.$||!this.S||this.J||(this.S=!1,this.La())};e.vd=function(){this.J=null;this.S&&!this.$&&(this.S=!1,this.La())};
2025 e.La=function(){var a=this.Ia,b=this.ad;if("function"!=q(a))if(a&&"function"==typeof a.handleEvent)a=u(a.handleEvent,a);else throw Error("Invalid listener argument");this.J=2147483647<Number(b)?-1:n.setTimeout(a,b||0);this.gd.apply(null,this.Ha)};var Za=H("Safari")&&!((H("Chrome")||H("CriOS"))&&!H("Edge")||H("Coast")||H("Opera")||H("Edge")||H("Silk")||H("Android"))&&!(H("iPhone")&&!H("iPod")&&!H("iPad")||H("iPad")||H("iPod"));var N=null,$a=null,ab=J||K&&!Za||Qa||"function"==typeof n.btoa,bb=function(a,b){var c;if(ab&&!b)c=n.btoa(a);else{c=[];for(var d=0,f=0;f<a.length;f++){for(var h=a.charCodeAt(f);255<h;)c[d++]=h&255,h>>=8;c[d++]=h}if(!N)for(N={},$a={},a=0;65>a;a++)N[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a),$a[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(a);b=b?$a:N;a=[];for(d=0;d<c.length;d+=3){var k=c[d],m=(f=d+1<c.length)?c[d+1]:0,v=(h=d+2<c.length)?
2026 c[d+2]:0,ha=k>>2,k=(k&3)<<4|m>>4,m=(m&15)<<2|v>>6,v=v&63;h||(v=64,f||(m=64));a.push(b[ha],b[k],b[m],b[v])}c=a.join("")}return c};var cb=function(a){if(a.l&&"function"==typeof a.l)return a.l();if(t(a))return a.split("");if(r(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return Fa(a)},db=function(a,b,c){if(a.forEach&&"function"==typeof a.forEach)a.forEach(b,c);else if(r(a)||t(a))x(a,b,c);else{var d;if(a.B&&"function"==typeof a.B)d=a.B();else if(a.l&&"function"==typeof a.l)d=void 0;else if(r(a)||t(a)){d=[];for(var f=a.length,h=0;h<f;h++)d.push(h)}else d=Ga(a);for(var f=cb(a),h=f.length,k=0;k<h;k++)b.call(c,f[k],
2027 d&&d[k],a)}};var O=function(a){this.h=new C;a&&this.addAll(a)},eb=function(a){var b=typeof a;return"object"==b&&a||"function"==b?"o"+(a[ja]||(a[ja]=++ka)):b.substr(0,1)+a};e=O.prototype;e.add=function(a){this.h.set(eb(a),a)};e.addAll=function(a){a=cb(a);for(var b=a.length,c=0;c<b;c++)this.add(a[c])};e.removeAll=function(a){a=cb(a);for(var b=a.length,c=0;c<b;c++)this.remove(a[c])};e.remove=function(a){return this.h.remove(eb(a))};e.clear=function(){this.h.clear()};e.contains=function(a){return this.h.M(eb(a))};
2028 e.l=function(){return this.h.l()};e.clone=function(){return new O(this)};e.v=function(){return this.h.v(!1)};var fb=function(a,b,c,d){Ia.call(this,a,d||6E5);this.Yd=b;this.Ma=c};aa(fb,Ia);fb.prototype.Eb=function(){this.Ma(new chrome.cast.Error(chrome.cast.u.TIMEOUT))};var P=function(a,b,c,d){this.type=a;this.message=b;this.sequenceNumber=void 0!==c?c:-1;this.timeoutMillis=d||0;this.clientId=""};var Q=function(a,b){this.Ia=a;this.D=b||String(Date.now())+String(Math.floor(1E5*Math.random()));this.L=null};Q.prototype.Qb=function(a){if(!this.L)return R.error("No active session"),"No active session";a.clientId=this.D;a=JSON.stringify(a);if(32768<a.length)return R.error("Message length over limit"),"Message length over limit";R.Bb("Send "+a);this.L.send(a);return null};Q.prototype.connect=function(a){this.L=a;this.L.onmessage=u(this.qd,this);this.Qb(new P("client_connect",this.D))};
2029 Q.prototype.disconnect=function(){this.L.close();this.L=null};Q.prototype.qd=function(a){R.Bb("Receive "+a.data);a=JSON.parse(a.data);if(a.clientId==this.D)this.Ia.onMessage(a)};var R=La("mr.cast.ExtensionMessenger");var gb=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#([\s\S]*))?$/,hb=function(a,b){if(a){a=a.split("&");for(var c=0;c<a.length;c++){var d=a[c].indexOf("="),f,h=null;0<=d?(f=a[c].substring(0,d),h=a[c].substring(d+1)):f=a[c];b(f,h?decodeURIComponent(h.replace(/\+/g," ")):"")}}};var S=function(a,b){this.X=this.ea=this.C="";this.P=null;this.Z=this.H="";this.m=this.ed=!1;var c;a instanceof S?(this.m=void 0!==b?b:a.m,this.Aa(a.C),this.$a(a.ea),this.xa(a.X),this.Ya(a.P),this.za(a.H),this.Za(a.w.clone()),this.ya(a.Z)):a&&(c=String(a).match(gb))?(this.m=!!b,this.Aa(c[1]||"",!0),this.$a(c[2]||"",!0),this.xa(c[3]||"",!0),this.Ya(c[4]),this.za(c[5]||"",!0),this.Za(c[6]||"",!0),this.ya(c[7]||"",!0)):(this.m=!!b,this.w=new T(null,null,this.m))};e=S.prototype;
2030 e.toString=function(){var a=[],b=this.C;b&&a.push(U(b,ib,!0),":");var c=this.X;if(c||"file"==b)a.push("//"),(b=this.ea)&&a.push(U(b,ib,!0),"@"),a.push(encodeURIComponent(String(c)).replace(/%25([0-9a-fA-F]{2})/g,"%$1")),c=this.P,null!=c&&a.push(":",String(c));if(c=this.H)this.Oa()&&"/"!=c.charAt(0)&&a.push("/"),a.push(U(c,"/"==c.charAt(0)?jb:kb,!0));(c=this.Tc())&&a.push("?",c);(c=this.Z)&&a.push("#",U(c,lb));return a.join("")};
2031 e.resolve=function(a){var b=this.clone(),c=a.Yc();c?b.Aa(a.C):c=a.Zc();c?b.$a(a.ea):c=a.Oa();c?b.xa(a.X):c=a.Wc();var d=a.H;if(c)b.Ya(a.P);else if(c=a.Cb()){if("/"!=d.charAt(0))if(this.Oa()&&!this.Cb())d="/"+d;else{var f=b.H.lastIndexOf("/");-1!=f&&(d=b.H.substr(0,f+1)+d)}f=d;if(".."==f||"."==f)d="";else if(-1!=f.indexOf("./")||-1!=f.indexOf("/.")){for(var d=0==f.lastIndexOf("/",0),f=f.split("/"),h=[],k=0;k<f.length;){var m=f[k++];"."==m?d&&k==f.length&&h.push(""):".."==m?((1<h.length||1==h.length&&
2032 ""!=h[0])&&h.pop(),d&&k==f.length&&h.push("")):(h.push(m),d=!0)}d=h.join("/")}else d=f}c?b.za(d):c=a.Xc();c?b.Za(a.w.clone()):c=a.Vc();c&&b.ya(a.Z);return b};e.clone=function(){return new S(this)};e.Aa=function(a,b){this.F();if(this.C=b?V(a,!0):a)this.C=this.C.replace(/:$/,"");return this};e.Yc=function(){return!!this.C};e.$a=function(a,b){this.F();this.ea=b?V(a):a;return this};e.Zc=function(){return!!this.ea};e.xa=function(a,b){this.F();this.X=b?V(a,!0):a;return this};e.Oa=function(){return!!this.X};
2033 e.Ya=function(a){this.F();if(a){a=Number(a);if(isNaN(a)||0>a)throw Error("Bad port number "+a);this.P=a}else this.P=null;return this};e.Wc=function(){return null!=this.P};e.za=function(a,b){this.F();this.H=b?V(a,!0):a;return this};e.Cb=function(){return!!this.H};e.Xc=function(){return""!==this.w.toString()};e.Za=function(a,b){this.F();a instanceof T?(this.w=a,this.w.Wa(this.m)):(b||(a=U(a,mb)),this.w=new T(a,null,this.m));return this};e.Tc=function(){return this.w.toString()};
2034 e.ya=function(a,b){this.F();this.Z=b?V(a):a;return this};e.Vc=function(){return!!this.Z};e.F=function(){if(this.ed)throw Error("Tried to modify a read-only Uri");};e.Wa=function(a){this.m=a;this.w&&this.w.Wa(a);return this};
2035 var V=function(a,b){return a?b?decodeURI(a.replace(/%25/g,"%2525")):decodeURIComponent(a):""},U=function(a,b,c){return t(a)?(a=encodeURI(a).replace(b,nb),c&&(a=a.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),a):null},nb=function(a){a=a.charCodeAt(0);return"%"+(a>>4&15).toString(16)+(a&15).toString(16)},ib=/[#\/\?@]/g,kb=/[\#\?:]/g,jb=/[\#\?]/g,mb=/[\#\?@]/g,lb=/#/g,T=function(a,b,c){this.f=this.c=null;this.A=a||null;this.m=!!c};e=T.prototype;
2036 e.G=function(){if(!this.c&&(this.c=new C,this.f=0,this.A)){var a=this;hb(this.A,function(b,c){a.add(decodeURIComponent(b.replace(/\+/g," ")),c)})}};e.add=function(a,b){this.G();this.O();a=this.N(a);var c=this.c.get(a);c||this.c.set(a,c=[]);c.push(b);this.f+=1;return this};e.remove=function(a){this.G();a=this.N(a);return this.c.M(a)?(this.O(),this.f-=this.c.get(a).length,this.c.remove(a)):!1};e.clear=function(){this.O();this.c=null;this.f=0};e.M=function(a){this.G();a=this.N(a);return this.c.M(a)};
2037 e.B=function(){this.G();for(var a=this.c.l(),b=this.c.B(),c=[],d=0;d<b.length;d++)for(var f=a[d],h=0;h<f.length;h++)c.push(b[d]);return c};e.l=function(a){this.G();var b=[];if(t(a))this.M(a)&&(b=Aa(b,this.c.get(this.N(a))));else{a=this.c.l();for(var c=0;c<a.length;c++)b=Aa(b,a[c])}return b};e.set=function(a,b){this.G();this.O();a=this.N(a);this.M(a)&&(this.f-=this.c.get(a).length);this.c.set(a,[b]);this.f+=1;return this};e.get=function(a,b){a=a?this.l(a):[];return 0<a.length?String(a[0]):b};
2038 e.Xd=function(a,b){this.remove(a);0<b.length&&(this.O(),this.c.set(this.N(a),Ba(b)),this.f+=b.length)};e.toString=function(){if(this.A)return this.A;if(!this.c)return"";for(var a=[],b=this.c.B(),c=0;c<b.length;c++)for(var d=b[c],f=encodeURIComponent(String(d)),d=this.l(d),h=0;h<d.length;h++){var k=f;""!==d[h]&&(k+="="+encodeURIComponent(String(d[h])));a.push(k)}return this.A=a.join("&")};e.O=function(){this.A=null};
2039 e.clone=function(){var a=new T;a.A=this.A;this.c&&(a.c=this.c.clone(),a.f=this.f);return a};e.N=function(a){a=String(a);this.m&&(a=a.toLowerCase());return a};e.Wa=function(a){a&&!this.m&&(this.G(),this.O(),this.c.forEach(function(a,c){var b=c.toLowerCase();c!=b&&(this.remove(c),this.Xd(b,a))},this));this.m=a};e.extend=function(a){for(var b=0;b<arguments.length;b++)db(arguments[b],function(a,b){this.add(b,a)},this)};var ob=function(a,b,c,d,f,h,k,m,v,ha){this.Mc=a;this.D=b||null;this.tb=c||null;this.yb=d||null;this.Db=void 0!==f?f:null;this.sb=h||null;this.Ab=k||null;this.bd=m||!1;this.vb=v||null;this.ub=ha||null};
2040 ob.prototype.toString=function(){var a=new S;a.Aa("https");a.xa("google.com");a.za("/cast");var b=[];x(this.Mc,function(a){var c="__castAppId__="+a.appId;a.capabilities&&0<a.capabilities.length&&(c=c+"("+a.capabilities.join(","),c+=")");b.push(c)});this.D&&b.push("__castClientId__="+this.D);this.tb&&b.push("__castAutoJoinPolicy__="+this.tb);this.yb&&b.push("__castDefaultActionPolicy__="+this.yb);null!=this.Db&&b.push("__castLaunchTimeout__="+this.Db);this.sb&&b.push("__dialAppName__="+this.sb);this.Ab&&
2041 b.push("__dialPostData__="+this.Ab);this.bd&&b.push("__castInvisibleSender__=true");this.vb&&(b.push("__castBroadcastNamespace__="+this.vb),b.push("__castBroadcastId__="+Math.random()));this.ub&&b.push("__castBroadcastMessage__="+encodeURIComponent(JSON.stringify(this.ub)));a.ya(b.join("/"));return a.toString()};var W=function(){this.R={};this.ra={}};W.prototype.Pd=function(a,b){var c=this,d=this.R[a];return d?(d.status=b,d.media.forEach(function(a){delete c.ra[a.sessionId+"#"+a.mediaSessionId]}),delete this.R[a],!0):!1};
2042 W.prototype.Rc=function(a){var b=this,c=this.R[a.sessionId];if(c)return c.statusText=a.statusText,c.namespaces=a.namespaces||[],c.receiver.volume=a.receiver.volume,c;var c=new chrome.cast.b(a.sessionId,a.appId,a.displayName,a.appImages,a.receiver),d;for(d in a)"media"==d?c.media=a.media.map(function(a){a=b.xb(a);a.ee=!1;a.na=!0;return a}):a.hasOwnProperty(d)&&(c[d]=a[d]);return this.R[a.sessionId]=c};
2043 W.prototype.xb=function(a){var b=a.sessionId+"#"+a.mediaSessionId,c=this.ra[b];c||(c=new chrome.cast.media.a(a.sessionId,a.mediaSessionId),this.ra[b]=c,(b=this.R[a.sessionId])&&b.media.push(c));b=c;b.currentItemId=null;b.loadingItemId=null;b.preloadedItemId=null;for(var d in a)"items"!=d&&a.hasOwnProperty(d)&&("volume"==d?(b.volume.level=a.volume.level,b.volume.muted=a.volume.muted):b[d]=a[d]);"currentTime"in a&&(b.Pa=Date.now());if(b.playerState==chrome.cast.media.T.IDLE&&null==b.loadingItemId)b.currentItemId=
2044 null,b.loadingItemId=null,b.preloadedItemId=null,b.items=null;else if(a.hasOwnProperty("items")&&a.items){d=[];var f=b.items,h={};if(f)for(var k=0;k<f.length;k++)h[f[k].itemId]=k;a=a.items;l();a=(f=a[Symbol.iterator])?f.call(a):fa(a);for(f=a.next();!f.done;f=a.next()){f=f.value;if(!f.media){var k=f.itemId,m=b.items?b.items[h[k]]:null;m&&m.media?f.media=m.media:k==b.currentItemId&&b.media&&(f.media=b.media)}d.push(pb(f))}b.items=d}return c};
2045 W.prototype.Md=function(a){delete this.ra[a.sessionId+"#"+a.mediaSessionId];var b=this.R[a.sessionId];b&&(a=b.media.indexOf(a),-1!=a&&b.media.splice(a,1))};var pb=function(a){var b=new chrome.cast.media.ib(a.media),c;for(c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b};var X=function(){this.Y=new Q(this);this.j=null;this.wa=new W;this.va=0;this.Ja=new E;this.ca=new C;this.Hb=!1;this.W=new C;this.qa=new C;this.ua=[];this.Pc=this.Qc.bind(this);this.I=null;this.pa=0;this.K=null;this.Oc=new Ya(this.Sd,200,this);this.zb=null},qb=function(a,b){a&&a(b)};e=X.prototype;e.ja=function(a,b,c){return new fb(this.va,a,b,c)};
2046 e.ba=function(a,b,c){b&&this.Ja.Kc(b);void 0!==c?a.sequenceNumber=c:(a.sequenceNumber=this.va,this.va=(this.va+1)%9007199254740992);c=this.Y.Qb(a);b&&c&&(a=this.Ja.Kb(a.sequenceNumber),b=new chrome.cast.Error(chrome.cast.u.INVALID_PARAMETER,c),(a=a.Ma)&&a(b))};
2047 e.oa=function(a,b){var c=this;y=this;this.j||(this.j=a,a.invisibleSender||(a=new PresentationRequest(this.la()),a.getAvailability().then(function(a){a.onchange=function(){c.Hb=!!a.value;c.j.receiverListener(a.value?chrome.cast.ha.AVAILABLE:chrome.cast.ha.UNAVAILABLE)};a.onchange()},function(){c.j.receiverListener(chrome.cast.ha.AVAILABLE)}),a.onconnectionavailable=function(a){c.sa(a.connection)},this.zb=(n.navigator||null).presentation.defaultRequest=a,a.reconnect(chrome.cast.Wb).then(function(a){c.sa(a)},
2048 ia)));b&&b(void 0)};e.Xa=function(a){a.navigator.presentation.defaultRequest=this.zb};e.sa=function(a,b){b=void 0===b?null:b;var c=this;a.onclose=function(a){c.I=null;switch(a.reason){case "closed":c.od();break;case "error":b&&(a=new chrome.cast.Error(chrome.cast.u.SESSION_ERROR),b&&b(a))}};a.onterminate=function(){c.td()};"connected"==a.state?this.Y.connect(a):a.onconnect=function(){c.Y.connect(a)}};
2049 e.Nc=function(a,b){"urn:x-cast:com.google.cast.media"!=a?Y.error("Unsupported broadcast message namespace - "+a):rb.has(b.type)?this.Hb&&(this.K?(b.sessionId=this.K,this.Va(null,b.type,b,function(){Y.info("Send Broadcast directly succeeded")},function(a){Y.error("Send Broadcast directly failed with code "+a.code)})):this.Oc.Sc(this.la(void 0,a,b))):Y.error("Unsupported broadcast message type - "+b.type)};
2050 e.Sd=function(a){Y.info("Broadcast request "+a);(a=(new PresentationRequest(a)).getAvailability())?a.then(function(){Y.info("Broadcast succeeded")},function(){Y.be("Broadcast failed")}):Y.error("presentationRequest.getAvailability return undefined")};
2051 e.requestSession=function(a,b,c){var d=this;this.I?qb(b,new chrome.cast.Error(chrome.cast.u.INVALID_PARAMETER,"Already requesting session")):(c=this.la(c),this.I=a,(new PresentationRequest(c.toString())).start().then(function(a){d.sa(a,b)}).catch(function(a){d.I=null;a=new chrome.cast.Error("AbortError"==a.name||"NotAllowedError"==a.name?chrome.cast.u.CANCEL:chrome.cast.u.SESSION_ERROR);b&&b(a)}))};
2052 e.la=function(a,b,c){var d=null,f=null,h=a||this.j.sessionRequest,k=h.dialRequest;k&&(d=k.appName,(f=k.launchParameter)&&!f.match(sb)&&(f=bb(f)));var m=[];m.push({appId:h.appId,capabilities:h.capabilities});a||x(this.j.additionalSessionRequests,function(a){m.push({appId:a.appId,capabilities:a.capabilities})});return(new ob(m,this.Y.D,this.j.autoJoinPolicy,this.j.defaultActionPolicy,h.requestSessionTimeout,d,f,this.j.invisibleSender,b,c)).toString()};
2053 e.Ob=function(a,b,c,d){var f=this;this.pa++;this.Va(null,b,a,function(a){f.pa--;a.na=!0;c&&c(a)},function(a){f.pa--;d(a)},chrome.cast.media.timeout.load)};e.i=function(a,b,c,d,f,h){var k=this;this.Va(a,b,c,function(a){k.wb(a);d&&d(void 0)},f,h)};e.Va=function(a,b,c,d,f,h){c.type=b;null!=a&&(c.mediaSessionId=a.mediaSessionId,c.sessionId=a.sessionId);this.Nb(c,function(a){a.status&&1==a.status.length?d&&d(a.status[0]):(a=new chrome.cast.Error(chrome.cast.u.SESSION_ERROR),f&&f(a))},f,h)};
2054 e.setReceiverVolume=function(a,b,c,d){b.sessionId=a;this.ba(new P("v2_message",b,void 0,chrome.cast.timeout.setReceiverVolume),this.ja(c,d,chrome.cast.timeout.sendCustomMessage))};e.Ta=function(a){var b=this;(new PresentationRequest(this.la())).reconnect(chrome.cast.kc+a).then(function(a){b.sa(a)},ia)};e.leaveSession=function(a,b,c){this.ba(new P("leave_session",a,void 0,chrome.cast.timeout.leaveSession),this.ja(b,c,chrome.cast.timeout.leaveSession))};
2055 e.Rd=function(a,b,c){this.ba(new P("app_message",a,void 0,chrome.cast.timeout.sendCustomMessage),this.ja(b,c,chrome.cast.timeout.sendCustomMessage))};e.Nb=function(a,b,c,d){this.ba(new P("v2_message",a,void 0,d),this.ja(b,c,d))};var tb=function(a,b,c){var d=a.get(b);d||(d=new O,a.set(b,d));d.add(c)};e=X.prototype;e.Lc=function(a,b){tb(this.ca,a,b)};e.Qd=function(a,b){(a=this.ca.get(a))&&a.remove(b)};e.Fa=function(a){this.ua.push(a)};e.Ra=function(a){a=this.ua.indexOf(a);0<=a&&this.ua.splice(a,1)};
2056 e.Hc=function(a,b,c){var d=this.W.get(a);d||(d=new C,this.W.set(a,d));a=d.get(b);a||(a=new O,d.set(b,a));a.add(c)};e.Ld=function(a,b,c){(a=this.W.get(a))&&(b=a.get(b))&&b.remove(c)};e.Ea=function(a,b){tb(this.qa,a,b)};e.Qa=function(a,b){(a=this.qa.get(a))&&a.remove(b)};e.Ic=function(a,b){-1==a.da.indexOf(b)&&a.da.push(b)};e.Nd=function(a,b){b=a.da.indexOf(b);-1!=b&&a.da.splice(b,1)};e.cd=function(a){var b=this.Ja.Kb(a.sequenceNumber);b&&(b="error"==a.type?b.Ma:b.Yd)&&b(a.message)};
2057 e.dd=function(a){return a.playerState!=chrome.cast.media.T.IDLE||null!=a.loadingItemId};e.wb=function(a){if(a.na){var b=this.dd(a);a.da.forEach(function(a){a(b)});b||this.wa.Md(a)}else if(!(0<this.pa)){a.na=!0;var c=this.qa.get(a.sessionId);c&&B(c.v(),function(b){b(a)})}};e.Qc=function(a){return this.wa.xb(a)};e.kd=function(a){switch(a.type){case "new_session":case "update_session":a.message=this.wa.Rc(a.message);break;case "v2_message":(a=a.message)&&"MEDIA_STATUS"==a.type&&a.status&&(a.status=a.status.map(this.Pc))}};
2058 e.Lb=function(a){if(this.K){var b=this.K;this.K=null;this.Y.disconnect();var c=a!=chrome.cast.U.STOPPED;this.wa.Pd(b,a)&&(this.W.remove(b),this.qa.remove(b),a=this.ca.get(b))&&(this.ca.remove(b),B(a.v(),function(a){a(c)}))}};
2059 e.onMessage=function(a){this.kd(a);this.cd(a);var b=a.message;if(b)switch(a.type){case "receiver_action":this.sd(b);break;case "new_session":this.rd(b);break;case "update_session":this.wd(b);break;case "app_message":this.md(b);break;case "v2_message":this.xd(b);break;case "custom_dial_launch":this.nd(a.sequenceNumber,b)}};e.rd=function(a){this.K=a.sessionId;this.I?(this.I(a),this.I=null):this.j&&this.j.sessionListener(a)};e.wd=function(a){(a=this.ca.get(a.sessionId))&&B(a.v(),function(a){a(!0)})};
2060 e.sd=function(a){this.ua.forEach(function(b){b(a.receiver,a.action)})};e.od=function(){this.Lb(chrome.cast.U.DISCONNECTED)};e.td=function(){this.Lb(chrome.cast.U.STOPPED)};e.md=function(a){var b=this.W.get(a.sessionId);b&&(b=b.get(a.namespaceName))&&B(b.v(),function(b){b(a.namespaceName,a.message)})};e.xd=function(a){"MEDIA_STATUS"==a.type&&a.status.forEach(this.wb.bind(this))};e.Ua=function(a,b){this.ba(new P("custom_dial_launch",b,void 0,chrome.cast.timeout.sendCustomMessage),null,a)};
2061 e.nd=function(a,b){var c=this;this.j.customDialLaunchCallback?this.j.customDialLaunchCallback(b).then(function(b){c.Ua(a,b)},function(){c.Ua(a)}):this.Ua(a)};var sb=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,rb=new Set(["PRECACHE"]),Z=new X,Y=La("mr.cast.Api");chrome.cast.oa=function(a,b,c){Z.oa(a,b,c)};p("chrome.cast.initialize",chrome.cast.oa,void 0);chrome.cast.$c=function(a,b,c){var d=new X;d.oa(a,b,c);return d};p("chrome.cast.initializeWithContext",chrome.cast.$c,void 0);chrome.cast.Xa=function(a){Z.Xa(a)};p("chrome.cast.setPageContext",chrome.cast.Xa,void 0);chrome.cast.requestSession=function(a,b,c){Z.requestSession(a,b,c)};p("chrome.cast.requestSession",chrome.cast.requestSession,void 0);
2062 chrome.cast.yd=function(a){Z.Nc("urn:x-cast:com.google.cast.media",new chrome.cast.media.mc(a))};p("chrome.cast.precache",chrome.cast.yd,void 0);chrome.cast.Ta=function(a){chrome.cast.Mb(Z,a)};p("chrome.cast.requestSessionById",chrome.cast.Ta,void 0);chrome.cast.Mb=function(a,b){a.Ta(b)};p("chrome.cast.requestSessionByIdWithContext",chrome.cast.Mb,void 0);chrome.cast.Fa=function(a){Z.Fa(a)};p("chrome.cast.addReceiverActionListener",chrome.cast.Fa,void 0);chrome.cast.Ra=function(a){Z.Ra(a)};
2063 p("chrome.cast.removeReceiverActionListener",chrome.cast.Ra,void 0);chrome.cast.jd=function(){};p("chrome.cast.logMessage",chrome.cast.jd,void 0);chrome.cast.Td=function(a,b){b()};p("chrome.cast.setCustomReceivers",chrome.cast.Td,void 0);chrome.cast.Ud=function(a,b){b()};p("chrome.cast.setReceiverDisplayStatus",chrome.cast.Ud,void 0);chrome.cast.unescape=function(a){return-1!=a.indexOf("&")?"document"in n?xa(a):ya(a):a};p("chrome.cast.unescape",chrome.cast.unescape,void 0);
2064 chrome.cast.isAvailable=!1;p("chrome.cast.isAvailable",chrome.cast.isAvailable,void 0);chrome.cast.Tb=!1;chrome.cast.ab=function(){if(!chrome.cast.Tb){chrome.cast.Tb=!0;chrome.cast.isAvailable=!0;var a=window.__onGCastApiAvailable;a&&"function"==typeof a&&a(!0)}};"complete"==document.readyState?chrome.cast.ab():(window.addEventListener("load",chrome.cast.ab,!1),window.addEventListener("DOMContentLoaded",chrome.cast.ab,!1));}).call(window);
2065(function(window) {
2066 'use strict';
2067
2068 var selectors = {
2069 controls: {
2070 bar: '.controlBar',
2071
2072 container: '.controlBar .front',
2073 play: '.play',
2074 pause: '.pause',
2075 replay: '.replay',
2076 bigPlay: '.playerStateIcon',
2077
2078 nextVideoTooltip: '.nextVideoTooltip',
2079
2080 time: {
2081 container: '.time',
2082 elapsed: '.elapsed',
2083 total: '.total'
2084 },
2085
2086 fullscreen: {
2087 button: '.fullscreen',
2088 on: '.fullscreenOn',
2089 off: '.fullscreenOff'
2090 },
2091
2092 chromecast: {
2093 button: '.chromecast',
2094 castBtn: '.chromecast .chromecastBtn'
2095 },
2096
2097 cinema: {
2098 button: '.cinema',
2099 normal: '.cinema .normal',
2100 large: '.cinema .large'
2101 },
2102
2103 volume: {
2104 button: '.volume',
2105 low: '.btn.volume-low',
2106 full: '.btn.volume-full',
2107 mute: '.btn.volume-mute',
2108
2109 sliderPlugin: {
2110 container: '.volumeSlider',
2111 zone: '.volumeBar',
2112 mask: '.volumeBar .front',
2113 handle: '.handle',
2114 //the extraClickZone parameters will accept more than one element separated by a comma jQuery style.
2115 extraClickZone: '.left, .right',
2116 covers: '.leftVolumeBarCover, .rightVolumeBarCover'
2117 }
2118 },
2119
2120 seekBar: {
2121 container: '.seekBar',
2122 bar: '.seekBar .progressPadding',
2123 buffer: '.seekBar .progressOverflow',
2124 background: '.seekBar .progressOverflow .background',
2125 //buffer: '.seekBar .buffer',
2126 progress: '.seekBar .progressOverflow .progress',
2127 handle: '.seekBar .handle'
2128 },
2129
2130 options: {
2131 container: '.options',
2132 button: '.options .btn',
2133 menu: {
2134 container: '.optionsPopup',
2135 list: '.optionsPopup ul',
2136 items: '.optionsPopup ul li',
2137 adaptive: '.optionsPopup .adaptive'
2138 },
2139 optionsPopup: '.optionsPopup',
2140 switchers: '.switchers',
2141 autoplay: '.optionsPopup .autoplay'
2142 },
2143
2144 logo: '.controlBar .logo'
2145 },
2146 actionTag: '.actionTag',
2147 preRollTitle: '.preRollTitle',
2148 preRollSkipButton: '.preRollSkipButton',
2149 eventCatcher: '.eventCatcher',
2150 share: '.share',
2151
2152 thumbnails: {
2153 container: '.thumbnails',
2154 image: '.thumbnails img.image',
2155 sprite: '.thumbnails .sprite',
2156 arrow: '.thumbnails .arrow',
2157 selectedTime: '.thumbnails .selectedTime',
2158 actionTagTitle: '.thumbnails .actionTagTitle'
2159 },
2160 videoErrorMessage: {
2161 container: '.videoErrorMessage',
2162 text: '.videoErrorMessage p'
2163 },
2164 topBar: {
2165 container: '.topBar',
2166 title: '.topBar .title span',
2167 share: '.topBar .share'
2168 },
2169 tooltip: {
2170 container: '.tooltip',
2171 title: '.tooltip .title',
2172 arrow: '.tooltip .arrow'
2173 },
2174 contextMenu: {
2175 container: '.contextMenu',
2176 copyUrlVideo: '.contextMenu .copyUrlVideo',
2177 copyUrlVideoTime: '.contextMenu .copyUrlVideoTime',
2178 copyEmbed: '.contextMenu .copyEmbed',
2179 about: '.contextMenu .about'
2180 },
2181 versionsInfo: {
2182 container: '.versionsInfo',
2183 copyCloseDiv : {
2184 container: '.copyCloseDiv',
2185 hideVersionMenu: '.copyCloseDiv .hideVersionMenu',
2186 copyMenu: '.copyCloseDiv .copyMenu'
2187 },
2188 playerVersions : {
2189 container: '.playerVersions',
2190 versionInfo: '.playerVersions .playerVersionContainer',
2191 streamingInfo: '.playerVersions .streamingInfoContainer',
2192 prerollInfo: '.playerVersions .prerollInfoContainer'
2193 }
2194 },
2195 hotspots: {
2196 container: '.seekBar .hotspots',
2197 svg: '.hotspots svg',
2198 polygon: '.hotspots polygon',
2199 progress: '.hotspots .hotspotsFill'
2200 },
2201 bufferingWheel: '.playerStateIcon .buffering'
2202 };
2203
2204 window.MHP1138 = window.MHP1138 || {};
2205 window.MHP1138.selectors = selectors;
2206})(window);
2207
2208__.mixin({
2209 ajaxLoader: function(path, callback, error) {
2210 var xmlhttp;
2211
2212 xmlhttp = new XMLHttpRequest();
2213 //xmlhttp.timeout = 10000; // 10sec
2214
2215 if (__.isFunction(callback)) {
2216 xmlhttp.onreadystatechange = function() {
2217 if (xmlhttp.readyState == XMLHttpRequest.DONE) {
2218 if (xmlhttp.status == 200) {
2219 callback(xmlhttp.responseText, xmlhttp.responseXML);
2220 }
2221
2222 if (__.isFunction(error)) {
2223 if (xmlhttp.status == 500 || xmlhttp.status == 404) {
2224 error();
2225 }
2226 }
2227 }
2228
2229 }
2230 }
2231
2232 xmlhttp.open("GET", path, true);
2233 xmlhttp.send();
2234 }
2235});
2236
2237__.mixin({
2238 // we use zest lib to resolve selectors, but in most cases
2239 // we dont need an array of elements, but just the first one
2240 // xest is a macro for those calls, saves us some bytes
2241 xest: function(sel) {
2242 return zest(sel)[0];
2243 },
2244
2245 fireEvent: function(player, eventName, additionalOptions) {
2246 var options = {
2247 playerType: player.playerType,
2248 element: player.playerContainerElement
2249 };
2250 __.extend(options, additionalOptions);
2251
2252 MHP1138.player.fireEvent(eventName, player.playerId, options);
2253 }
2254})
2255
2256// Creating a Delay for any actions or events
2257
2258__.mixin({
2259 debounce: function(func, wait, immediate) {
2260 var timeout;
2261 return function() {
2262 var context = this, args = arguments;
2263 var later = function() {
2264 timeout = null;
2265 if (!immediate) func.apply(context, args);
2266 };
2267 var callNow = immediate && !timeout;
2268 clearTimeout(timeout);
2269 timeout = setTimeout(later, wait);
2270 if (callNow) func.apply(context, args);
2271 };
2272 }
2273});
2274
2275//innerHTML don't run script, so this extract them so they can be appended to the document in a different way.
2276//it also add the class prefix to every class.
2277var mhp_cssClassRegex = /\.-?[_a-zA-Z]+[_a-zA-Z0-9-]*(?=[^}]*\{)(?!.*\*\/)/g; //http://regexr.com/3b877
2278__.mixin({
2279 colorLuminance: function(hex, lum){
2280 // validate hex string
2281 hex = String(hex).replace(/[^0-9a-f]/gi, '');
2282 if (hex.length < 6) {
2283 hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
2284 }
2285 lum = lum || 0;
2286
2287 // convert to decimal and change luminosity
2288 var rgb = "#", c, i;
2289 for (i = 0; i < 3; i++) {
2290 c = parseInt(hex.substr(i*2,2), 16);
2291 c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
2292 rgb += ("00"+c).substr(c.length);
2293 }
2294
2295 return rgb;
2296 },
2297 addPrefixToSkinElements: function(originalObject, prefix, playerId){
2298 var newObject = {};
2299
2300 __.each(originalObject, function(value, key){
2301 if( __.isObject(value) ){
2302 newObject[key] = __.addPrefixToSkinElements(value, prefix, playerId);
2303 }else{
2304 newObject[key] = '#' + playerId + ' ' + value.replace(/\./g, '.' + prefix + '_');
2305 }
2306 });
2307
2308 return newObject;
2309 },
2310 addPrefixAndColorToSkinThemeCss: function(originalObject, prefix, playerId, themeColor){
2311 var newObject = [];
2312
2313 __.each(originalObject, function(css, key){
2314 //add prefix to classes
2315 var css = css.replace(mhp_cssClassRegex, function(string){
2316 return '.' + prefix + '_' + string.substring(1);
2317 });
2318
2319 //add player id before css declaration
2320 css = '#' + playerId + ' ' + css;
2321
2322 //change "themeColor(number)" in the css to the theme color.. if (number) is present after it modify the color luminosity
2323 //http://regexr.com/3bh7g
2324 css = css.replace(/themeColor(\(([\d-\.]+)\))?/, function(){
2325 if( !__.isUndefined(arguments[2]) && !__.isNaN(arguments[2]) ){
2326 return __.colorLuminance(themeColor, arguments[2]);
2327 }else{
2328 return themeColor;
2329 }
2330 });
2331
2332 newObject.push(css);
2333 });
2334
2335 return newObject;
2336 }
2337});
2338
2339__.mixin({
2340 toMarkup: function(markup, prefix){
2341 var finalMarkup = '';
2342 __.each(markup, function(code, key) {
2343 if ( __.isObject(code)) {
2344 var attributes = code['_attributes'] || '';
2345 delete code['_attributes'];
2346 finalMarkup += satisfy('.'+ key + attributes + '[html='+ __.toMarkup(code, prefix) +']', prefix)[0].outerHTML;
2347 } else {
2348 var elements = '';
2349
2350 if (!__.isNull(code))
2351 __.each(satisfy(code, prefix), function(item){
2352 elements += item.outerHTML;
2353 });
2354
2355 finalMarkup += satisfy('.' + key + ((elements.length) ? '[html='+ elements +']' : ''), prefix)[0].outerHTML;
2356 }
2357 });
2358 return finalMarkup;
2359 }
2360});
2361
2362__.mixin({
2363 secondToTime: function(time, separator){
2364 separator = separator || ':';
2365
2366 var hours = Math.floor(time / 3600);
2367
2368 time = time - hours * 3600;
2369
2370 var minutes = Math.floor(time / 60);
2371 var seconds = Math.floor(time % 60);
2372
2373 hours = (hours > 0 && hours < 10) ? '0' + hours : hours;
2374 minutes = (minutes < 10) ? '0' + minutes : minutes;
2375 seconds = (seconds < 10) ? '0' + seconds : seconds;
2376
2377 return ((hours) ? hours + separator : '') + minutes + separator + seconds;
2378 }
2379});
2380
2381//Will check the z-index of an element and all it's children and return the highest z-index found.
2382//Usefull to be sure an element that catch events is over it's childrens whitout having to set a ridiculous z-index.
2383//Will return 0 in case of negative value.
2384__.mixin({
2385 getTopIndex: function(element){
2386 var topIndex = 0;
2387 var thisIndex = parseInt(window.getComputedStyle(element).zIndex);
2388
2389 if( !__.isNaN(thisIndex) && thisIndex > topIndex )
2390 topIndex = parseInt(thisIndex);
2391
2392 if( element.childNodes.length ){
2393 __.each(element.childNodes, function(el){
2394 var childrenTopIndex = __.getTopIndex(el);
2395
2396 if( childrenTopIndex > topIndex )
2397 topIndex = childrenTopIndex;
2398 });
2399 }
2400
2401 return topIndex;
2402 }
2403});
2404
2405__.mixin({
2406 getElementsByClassName: function(node, classname){
2407 if(node.querySelectorAll){
2408 var a = [],
2409 x = node.querySelectorAll('.' + classname);
2410
2411 if(x.length){
2412 for(var i = 0, ln = x.length; i < ln; i++){
2413 a.push(x[i]);
2414 }
2415 }
2416
2417 return a;
2418 } else {
2419 var a = [];
2420 var re = new RegExp('(^| )'+classname+'( |$)');
2421 var els = node.getElementsByTagName("*");
2422 for(var i=0,j=els.length; i<j; i++)
2423 if(re.test(els[i].className))a.push(els[i]);
2424 return a;
2425 }
2426 }
2427});
2428
2429//Building simple hash from string
2430__.mixin({
2431 hashString: function(str) {
2432 var hash = 0;
2433 if (str.length === 0) return hash;
2434 for (var i = 0, l = str.length; i < l; i++) {
2435 var character = str.charCodeAt(i);
2436 hash = ((hash<<5)-hash)+character;
2437 hash = hash & hash; // Convert to 32bit integer
2438 }
2439 return Math.abs(hash);
2440 }
2441});
2442
2443(function(window) {
2444 'use strict';
2445
2446 var themeCss = [
2447 /* EXTRA CSS WITH THE THEME COLOR THAT WILL BE REPLACED ON THE CLIENT SIDE */
2448 /* THE CSS WILL BE APPENDED TO THE END OF ALL OTHER CSS */
2449 /* NORMAL CSS, NO PREPROCESOR (SASS) */
2450 /* themeColor = the default theme color */
2451 /* themeColor(-0.2) mean the theme color but 20% darker (luminosity) */
2452 /* themeColor(0.5) = 50% lighter */
2453 '.seekBar .progress { background-color: themeColor; }',
2454 '.volumeBar .front { background-color: themeColor; }',
2455 '.progress:before{ background: themeColor; }',
2456 '.buffering svg path.normal{ fill: themeColor; }',
2457 '.buffering svg path.faded1{ fill: themeColor(-0.3); }',
2458 '.buffering svg path.faded2{ fill: themeColor(-0.5); }',
2459 '.buffering svg path.faded3{ fill: themeColor(-0.7); }',
2460 '.controlBar .options .optionsPopup ul li.upsell span.icon-star { background: themeColor; }',
2461 '.controlBar .options .btn.isHD:after { background: themeColor; }',
2462 '.controlBar .options .optionsPopup .optionSwitch.stateOn span { background-color: themeColor; }',
2463 '.gridMenu .thumbnailsGrid .info .title { color: themeColor; }',
2464 '.videoErrorMessage a { color: themeColor; }',
2465 '.controlBar .nextVideoTooltip .text .title {color: themeColor;}',
2466 '.versionsInfo .playerVersions::-webkit-scrollbar-thumb {background-color: themeColor;}'
2467 ];
2468
2469 window.MHP1138 = window.MHP1138 || {};
2470 window.MHP1138.themeCss = themeCss;
2471})(window);
2472MHP1138.gridMenu = function() {
2473
2474 return {
2475 elements: {
2476 thumbnailsContainer: '.gridContainer',
2477 thumbnailsGrid: '.thumbnailsGrid',
2478 buttonContainer: '.controlBar .front',
2479 controls: {
2480 button: '.grid',
2481 }
2482 },
2483
2484 init: function(player) {
2485 this.player = player;
2486 this.skin = player.skin;
2487 this.settings = player.settings.menu;
2488 this.container = player.playerContainerElement;
2489
2490 // Grid menu available only for embeded mode
2491 if(!this.player.settings.embeds.enabled){
2492 return;
2493 }
2494
2495 this.subscribeToPlayerEvents();
2496 this.createGridMarkup();
2497 this.initCloseButton();
2498 },
2499
2500 createGridMarkup: function() {
2501 this.gridTemplate = __.template(__.xest('.mhp1138_gridTemplate').innerHTML);
2502 this.gridItemTemplate = __.template(__.xest('.mhp1138_gridItemTemplate').innerHTML.replace(/<%/g, '<%').replace(/%>/g, '%>'));
2503
2504 var menu = document.createElement('div');
2505 menu.className = 'mhp1138_gridMenu';
2506 menu.innerHTML = this.gridTemplate();
2507 // TODO: replace playerContainerElement to object passed in settings on init`
2508 this.container.appendChild(menu);
2509 this.menu = menu;
2510
2511 this.elements = __.addPrefixToSkinElements(
2512 this.elements,
2513 'mhp1138',
2514 this.player.playerId
2515 );
2516
2517 this.thumbnailsGrid = __.xest(this.elements.thumbnailsGrid);
2518 this.thumbnailsContainer = __.xest(this.elements.thumbnailsContainer);
2519 },
2520
2521 subscribeToPlayerEvents: function() {
2522 var self = this,
2523 playerId = this.player.playerId;
2524
2525 MHP1138.player.subscribeToEvent('onPlay', playerId, function() {
2526 self.hideMenu();
2527 });
2528
2529 MHP1138.player.subscribeToEvent('onSeek', playerId, function() {
2530 self.hideMenu();
2531 });
2532
2533 if (this.settings.showOnPause) {
2534 MHP1138.player.subscribeToEvent('onPause', playerId, function() {
2535 self.showMenu();
2536 });
2537 }
2538
2539 if (this.settings.showOnPost) {
2540 MHP1138.player.subscribeToEvent('onEnd', playerId, function() {
2541 self.showMenu();
2542 });
2543 }
2544
2545 },
2546
2547 loadData: function() {
2548 var self = this,
2549 settings = this.settings;
2550
2551 if (!__.isUndefined(settings.relatedUrl)) {
2552 settings.url = settings.relatedUrl;
2553 }
2554
2555 if (settings.data) {
2556 this.dataReady(settings.data);
2557 } else if (settings.url) {
2558 // TODO: add UI representation of the data being loaded, spinner or something
2559 __.ajaxLoader(settings.url, function(response) {
2560 self.dataReady(JSON.parse(response));
2561 });
2562 }
2563 },
2564
2565 dataReady: function(response) {
2566 this.data = response;
2567 this.page = 0;
2568
2569 // TODO: hide loading spinner, if exists
2570
2571 if (__.isUndefined(this.data)) {
2572 this.hideMenu();
2573 return false;
2574 }
2575 this.dataLoaded = true;
2576
2577 this.createThumbs();
2578 if (this.settings.deferredLoad) {
2579 this.showMenu();
2580 }
2581 },
2582
2583 initCloseButton: function() {
2584 var self = this;
2585 //this.closeButton = __.xest(this.elements.controls.closeButton);
2586 //this.closeButton.addEventListener('click', function() { self.hideMenu() });
2587
2588 // hide grid on empty space clicks
2589 this.menu.addEventListener('click', function() {
2590 var player = self.player;
2591 var embeds = player.settings.embeds;
2592 if (embeds.enabled) {
2593 var url = player.addUTM(player.addCurrentTimeToUrl(embeds.redirect.logoUrl), 'embed', 'embed-html5');
2594 player.openRedirectWindow(url);
2595 } else {
2596 self.hideMenu();
2597 }
2598 });
2599 },
2600
2601 createThumbs: function() {
2602 var page = this.page,
2603 data = this.data['related'],
2604 start = page * 9,
2605 end = start + 9,
2606 markup = '',
2607 i, item, count;
2608
2609 if (end > data.length) {
2610 end = data.length;
2611 }
2612
2613 count = end - start;
2614
2615 for (i = start; i < end; i++) {
2616 item = data[i];
2617 markup += this.gridItemTemplate({
2618 url : item[4],
2619 title : item[1],
2620 thumbnail : item[0],
2621 time : item[2],
2622 percentage : item[3]
2623 });
2624
2625 // special cases
2626 if (count == 4 && i - start == 1) {
2627 markup += '<br>';
2628 }
2629 }
2630
2631 // special cases
2632 if (count == 5 || count == 8) {
2633 markup += '<div class=mhp1138_gridItem></div>';
2634 }
2635
2636 // special cases
2637 if (count == 7) {
2638 markup += '<div class=mhp1138_gridItem></div>';
2639 markup += '<div class=mhp1138_gridItem></div>';
2640 }
2641
2642 this.thumbnailsGrid.innerHTML = markup;
2643 this.initGridLinks();
2644 },
2645
2646 initGridLinks: function() {
2647 var self = this,
2648 items = zest(this.elements.thumbnailsGrid + ' .mhp1138_gridItem'),
2649 embedsSettings = this.player.settings.embeds;
2650
2651 if (this.settings.linkColor) {
2652 var titles = zest(this.elements.thumbnailsGrid + ' .mhp1138_gridItem .mhp1138_title')
2653 __.each(titles, function(item) {
2654 item.style.color = self.settings.linkColor;
2655 });
2656 }
2657
2658 function eventHandler(e, item) {
2659 var url = self.player.addUTM(item.href, 'embed', 'embed-related-html5');
2660 self.player.openRedirectWindow(url);
2661 }
2662
2663 __.each(items, function(item) {
2664 if (item.tagName == 'A' && item.href.length) {
2665 //to handle mousewheel(middle) and right click
2666 item.addEventListener('mousedown', function(e){
2667 e.preventDefault();
2668 e.stopPropagation();
2669 if(e.which == 2 || e.which == 3) {
2670 eventHandler(e, item);
2671 }
2672 });
2673 //to handle left click and key events
2674 item.addEventListener('click', function(e){
2675 e.preventDefault();
2676 e.stopPropagation();
2677 if(e.which == 1){
2678 eventHandler(e, item);
2679 }
2680 });
2681 }
2682 });
2683 },
2684
2685 disableTab: function(key) {
2686 this.tabs[key].style.display = 'none';
2687 },
2688
2689 activateTab: function(key) {
2690 __.each(this.tabs, function(tab) {
2691 __.removeClass(tab, 'active');
2692 });
2693 __.addClass(this.tabs[key], 'active');
2694 this.activeTab = key;
2695
2696
2697 },
2698
2699 toggleMenu: function() {
2700 if (this.visible) {
2701 this.hideMenu();
2702 } else {
2703 this.showMenu();
2704 }
2705 },
2706
2707 showMenu: function() {
2708 //paused is fired at time of seeking, so shouldn't show grid menu when player is playing and seeked
2709 if (this.visible || this.skin.seekBarMouseDown || this.player.playing) return false;
2710
2711 if (!this.dataLoaded) {
2712 if (this.settings.deferredLoad) {
2713 this.loadData();
2714 }
2715 return false;
2716 }
2717 this.visible = true;
2718 __.addClass(this.container, 'showGrid');
2719 },
2720
2721 hideMenu: function() {
2722 if (!this.visible) return false;
2723
2724 this.visible = false;
2725 __.removeClass(this.container, 'showGrid');
2726 }
2727 };
2728};
2729(function(window, _) {
2730 'use strict';
2731
2732 var VolumeSlider = function(settings, s) {
2733 var volumeBtn,
2734 sliderContainer,
2735 zone,
2736 mask,
2737 playerContainer,
2738 isHorizontal = true,
2739 axis,
2740 startingSide,
2741 rangeOrientation,
2742 previousPosition = 0,
2743 currentPosition = 0,
2744 onChange,
2745 onStartDrag,
2746 onEndDrag,
2747 zoneOffset,
2748 mouseDown = false,
2749 volumeSliderHoverTimer,
2750 volumeSliderOpen = true,
2751 covers;
2752
2753
2754 function initEvents() {
2755
2756 function startDrag(e) {
2757 if (e.button == 0 || e.touches.length) {
2758 //stop text selection
2759 e.preventDefault();
2760
2761 mouseDown = true;
2762
2763 //we only calculate the bounding zone on the initial mousedown event to save cpu ressources
2764 //calculating it on every pixel the mouse move could use a lot of ressources for nothing.
2765 zoneOffset = zone.getBoundingClientRect();
2766
2767 //we call the same function as the mousemove once before enabling it.
2768 //that way a single click on the slider is also working whitout having to bind a separate click event.
2769 trackMousePosition(e);
2770
2771 //we initiate the mousemove events so the can drag the slider around.
2772 updateMouseEvent();
2773 //callback
2774 if (_.isFunction(onStartDrag)) {
2775 onStartDrag();
2776 }
2777 }
2778 }
2779 var volumeBarContainerHovered = true;
2780
2781 function endDrag(e) {
2782 if (!mouseDown) return false;
2783
2784 mouseDown = false;
2785 updateMouseEvent();
2786 if (!volumeBarContainerHovered) {
2787 autoHideVolumeSlider();
2788 }
2789
2790 //callback
2791 if (_.isFunction(onEndDrag)) {
2792 onEndDrag();
2793 }
2794 e.preventDefault();
2795 }
2796
2797 document.addEventListener('mouseup', endDrag);
2798
2799 zone.addEventListener('mousedown', startDrag);
2800 zone.addEventListener('touchstart', startDrag);
2801 zone.addEventListener('touchmove', trackMousePosition);
2802 zone.addEventListener('touchend', endDrag);
2803
2804 if (volumeBtn && sliderContainer) {
2805 volumeBtn.addEventListener('mouseenter', function() {
2806 showVolumeSlider();
2807 });
2808
2809 volumeBtn.addEventListener('mouseleave', function() {
2810 autoHideVolumeSlider();
2811 });
2812
2813 sliderContainer.addEventListener('mouseenter', function() {
2814 clearTimeout(volumeSliderHoverTimer);
2815 volumeBarContainerHovered = true;
2816 });
2817
2818 sliderContainer.addEventListener('mouseleave', function() {
2819 autoHideVolumeSlider()
2820 volumeBarContainerHovered = false;
2821 });
2822 }
2823
2824 }
2825
2826 function showVolumeSlider() {
2827 clearTimeout(volumeSliderHoverTimer);
2828 volumeSliderOpen = true;
2829 _.removeClass(sliderContainer, 'hidden');
2830 }
2831
2832 function hideVolumeSlider() {
2833 if (!mouseDown) {
2834 volumeSliderOpen = false;
2835 _.addClass(sliderContainer, 'hidden');
2836 }
2837 }
2838
2839 function autoHideVolumeSlider(timeout) {
2840 if (!timeout) timeout = 200;
2841 clearTimeout(volumeSliderHoverTimer);
2842 volumeSliderHoverTimer = setTimeout(hideVolumeSlider, timeout);
2843 }
2844
2845
2846 function disablePlayerEvents(e) {
2847 e.preventDefault();
2848 return false;
2849 }
2850
2851 function updateMouseEvent() {
2852 if (mouseDown) {
2853 // drag started
2854 document.addEventListener('mousemove', trackMousePosition, true);//need to handle event in capturing phase, as on streaming page volumeEventCapture doesn't fire event
2855 _.each(covers, function(cover) {
2856 cover.style.display = 'block';
2857 })
2858 } else {
2859 // drag ended
2860 document.removeEventListener('mousemove', trackMousePosition, true);//need to handle event in capturing phase, as on streaming page volumeEventCapture doesn't fire event
2861 _.each(covers, function(cover) {
2862 cover.style.display = 'none';
2863 })
2864 }
2865 }
2866
2867 function trackMousePosition(e) {
2868 var pageX;
2869 // touchstart array
2870 if (e.touches && e.touches.length) {
2871 pageX = e.touches[0].pageX
2872 // touchmove / touchend array, touches arr could be empty at this point
2873 } else if (e.changedTouches && e.changedTouches.length) {
2874 pageX = e.changedTouches[0].pageX
2875 } else {
2876 pageX = e.pageX;
2877 }
2878
2879 var position = pageX - (zoneOffset[startingSide] + window.pageXOffset),
2880 range = zoneOffset[rangeOrientation];
2881
2882 if (position > range) position = range;
2883 if (position < 0) position = 0;
2884
2885 previousPosition = currentPosition;
2886 currentPosition = pixelToPercent(position, range);
2887
2888 if (currentPosition !== previousPosition) {
2889 updatePosition(true);
2890 }
2891
2892 e.stopPropagation();
2893 e.preventDefault();
2894 }
2895
2896 function updatePosition(triggerCallback, animated) {
2897 zoneOffset = zone.getBoundingClientRect();
2898 var range = zoneOffset[rangeOrientation];
2899
2900 if (animated) {
2901 _.addClass(sliderContainer, 'animated');
2902 setTimeout(function() {
2903 _.removeClass(sliderContainer, 'animated');
2904 }, 200);
2905 }
2906 mask.style.width = percentToPixel(currentPosition, range) + 'px';
2907
2908 //callback
2909 if (_.isFunction(onChange) && triggerCallback) {
2910 onChange(currentPosition);
2911 }
2912 }
2913
2914 function pixelToPercent(pixel, range) {
2915 return Math.round((pixel * 100) / range);
2916 }
2917
2918 function percentToPixel(percentage, range) {
2919 return Math.round((percentage * range) / 100);
2920 }
2921
2922 //Elements
2923 playerContainer = settings.playerContainer;
2924
2925 volumeBtn = settings.volumeBtn;
2926 sliderContainer = settings.sliderContainer;
2927 zone = settings.zone;
2928 mask = settings.mask;
2929 covers = settings.covers;
2930
2931 //Settings
2932 isHorizontal = settings.horizontal;
2933 currentPosition = settings.startingPosition;
2934
2935 //Events (functions)
2936 onChange = settings.onChange;
2937 onStartDrag = settings.onStartDrag;
2938 onEndDrag = settings.onEndDrag;
2939
2940 axis = (isHorizontal) ? 'X' : 'Y';
2941 startingSide = (isHorizontal) ? 'left' : 'top';
2942 rangeOrientation = (isHorizontal) ? 'width' : 'height';
2943
2944 updatePosition(false);
2945 initEvents();
2946
2947 return {
2948 show: showVolumeSlider,
2949 hide: hideVolumeSlider,
2950 autoHide: autoHideVolumeSlider,
2951 setValue: function(percentage) {
2952 if (!_.isNaN(percentage)) {
2953 if (percentage > 100) percentage = 100;
2954 if (percentage < 0) percentage = 0;
2955
2956 currentPosition = percentage;
2957 updatePosition(false);
2958 }
2959 },
2960 getValue: function() {
2961 return currentPosition;
2962 }
2963 };
2964 };
2965
2966 window.MHP1138 = window.MHP1138 || {};
2967 window.MHP1138.VolumeSlider = VolumeSlider;
2968})(window, __);
2969MHP1138.vast = function() {
2970 return {
2971 videoReady: false,
2972 cachedFiles: {},
2973 status: 'empty',
2974 errorUrl: '',
2975 version: 0,
2976 errorCode: 0,
2977 linearAds: [],
2978 nonLinearAds: [],
2979 companionAds: [],
2980 addTitles: [],
2981
2982 init: function(player, settings, rollType) {
2983 this.player = player;
2984 this.playerSettings = player.settings;
2985 this.settings = settings;
2986 this.rollType = rollType;
2987
2988 if (__.isString(settings.xml)) {
2989 this.createXmlDom(settings.xml);
2990 }
2991 },
2992
2993 createXmlDom: function(xmlData) {
2994 var parser = new DOMParser();
2995 this.xml = parser.parseFromString(xmlData, "text/xml");
2996 if ((new XMLSerializer()).serializeToString(this.xml).indexOf('parsererror') != -1) {
2997 this.errorParsingXml();
2998 } else {
2999 this.status = 'created';
3000 this.parseData();
3001 }
3002 },
3003
3004 parseData: function() {
3005 var root = this.xml.documentElement;
3006
3007 this.version = parseFloat(root.getAttribute('version')) || 0;
3008
3009 this.parseErrorTracking(root);
3010 this.parseAds(root);
3011 this.checkUnsupportedVastFeatures(root);
3012
3013 this.rootNode = root;
3014 this.status = 'parsed';
3015 },
3016
3017 parseAds: function(root) {
3018 var self = this,
3019 ads = root.getElementsByTagName('Ad')
3020
3021 this.rolls = [];
3022 this.overlays = [];
3023 __.each(ads, function(ad) {
3024 self.checkUnsupportedAdFeatures(ad);
3025
3026 // converting 'HTMLCollections' returned by 'getElementsByTagName' to regular arrays
3027 // (to use Array.concat method later)
3028 var linears = [].slice.call(ad.getElementsByTagName('Linear')),
3029 nonLinears = [].slice.call(ad.getElementsByTagName('NonLinear')),
3030 companions = [].slice.call(ad.getElementsByTagName('Companion')),
3031 impression = [].slice.call(ad.getElementsByTagName('Impression')),
3032 adTitle = [].slice.call(ad.getElementsByTagName('AdTitle')),
3033 arrString = '';
3034
3035 if(__.isArray(impression)) {
3036 arrString = impression.map(function(el){
3037 return el.textContent;
3038 }).join('|');
3039 } else {
3040 arrString = impression[0].textContent;
3041 }
3042
3043 // HACKERY
3044 // apply impression (trackUrl) to each video roll object because it is located in the upper Ad structure
3045 // (not inside Linear node)
3046 if (impression.length) {
3047 __.each(linears, function(ad) {
3048 ad.setAttribute('impression', arrString)
3049 });
3050 }
3051
3052 self.addTitles=self.addTitles.concat(adTitle[0].textContent);
3053
3054 // regular video ad rolls
3055 self.linearAds = self.linearAds.concat(linears);
3056 // non linear ads will become overlays
3057 self.nonLinearAds = self.nonLinearAds.concat(nonLinears);
3058 // storing them for future generations
3059 self.companionAds = self.companionAds.concat(companions);
3060 });
3061
3062 __.each(this.linearAds, function(ad, index) {
3063 var roll = self.parseLinearAd(ad);
3064 roll.title = self.addTitles[index];
3065 if (roll) {
3066 self.rolls.push(roll);
3067 }
3068 });
3069
3070 __.each(this.nonLinearAds, function(ad) {
3071 var banner = self.parseNonLinearAd(ad);
3072 if (banner) {
3073 self.overlays.push(banner);
3074 }
3075 });
3076 },
3077
3078 parseLinearAd: function(ad) {
3079 var durationNodes = ad.getElementsByTagName('Duration'),
3080 skipDelay = this.parseTimeToSeconds(ad.getAttribute('skipoffset') || ''),
3081 videoUrl = this.getMediaSrcByQuality(ad, this.player.selectedResolution);
3082
3083 if (!__.isPath(videoUrl)) return false;
3084
3085 // merged settings
3086 var roll = __.deepExtend({}, this.playerSettings.defaultRollObject, this.settings.rollSettings)
3087
3088 // fill default object with data from xml
3089 roll.vastParser = true;
3090 roll.timing = this.rollType;
3091 roll.videoUrl = videoUrl;
3092
3093 // parseClickTracking methid returns the same roll with
3094 // created or updated clickUrl and clickTrackUrl fields
3095 roll.campaign = __.hashString(roll.campaignName).toString();
3096 roll = this.parseClickTracking(ad, roll);
3097 roll = this.parseImpressionTracking(ad, roll);
3098 roll.tracking = this.parseTrackingEvents(ad);
3099
3100 // use skipDelay from VAST config
3101 // could be dangerous
3102 if (this.settings.vastSkipDelay &&
3103 skipDelay > 0
3104 ) {
3105 roll.skipDelay = skipDelay;
3106 }
3107
3108 if (durationNodes.length) {
3109 roll.duration = this.parseTimeToSeconds(String(durationNodes[0].textContent).trim());
3110 }
3111
3112 return roll;
3113 },
3114
3115 parseNonLinearAd: function(ad) {
3116 // IframeResource and HTMLResource are basically the same entities
3117 var imageNodes = ad.getElementsByTagName('StaticResource'),
3118 htmlNodes = ad.getElementsByTagName('HTMLResource'),
3119 iframeNodes = ad.getElementsByTagName('IFrameResource'),
3120 overlay = {
3121 hCentered: true,
3122 border: true,
3123 closeButton: true,
3124 top: '10px',
3125 width: ad.getAttribute('width') || 0 + 'px',
3126 height: ad.getAttribute('height') || 0 + 'px',
3127 time: 0,
3128 duration: this.parseTimeToSeconds(ad.getAttribute('minSuggestedDuration') || '24:00:00')
3129 },
3130 imageUrl, iframeUrl, clickUrl, trackingUrl;
3131
3132 // check the nodes
3133 if (imageNodes.length) {
3134 imageUrl = String(imageNodes[0].textContent).trim();
3135 } else if (htmlNodes.length) {
3136 iframeUrl = String(htmlNodes[0].textContent).trim();
3137 } else if (iframeNodes.length) {
3138 iframeUrl = String(iframeNodes[0].textContent).trim();
3139 } else {
3140 return false;
3141 }
3142
3143 // check the data
3144 if (__.isPath(imageUrl)) {
3145 overlay.imageUrl = imageUrl
3146
3147 // extract more fields for static banner
3148 overlay = this.parseClickTracking(ad, overlay, 'NonLinear');
3149
3150 } else if (__.isPath(iframeUrl)) {
3151 overlay.iframeUrl = iframeUrl;
3152 } else {
3153 return false;
3154 }
3155
3156 // check the player dimensions to place the banner
3157
3158 // TODO: refactoring needed. Cant do this at this point, since player container is not initialized yet
3159 //
3160 // if (!this.checkOverlayDimensions(overlay)) {
3161 // this.reportError(501);
3162 // return false;
3163 // }
3164
3165 return overlay;
3166 },
3167
3168 checkOverlayDimensions: function(overlay) {
3169 var container = this.player.playerContainerElement;
3170 if (container.clientWidth < overlay.width ||
3171 container.clientHeight < overlay.height
3172 ) {
3173 return false;
3174 }
3175 return true;
3176 },
3177
3178 parseTimeToSeconds: function(time) {
3179 var parts = String(time).split(':'),
3180 seconds = 0;
3181 if (parts.length) {
3182 seconds = parseInt(parts[parts.length-1]);
3183 if (parts.length > 1) {
3184 seconds += parseInt(parts[parts.length-2])*60;
3185 }
3186 if (parts.length > 2) {
3187 seconds += parseInt(parts[parts.length-3])*60*60
3188 }
3189 } else {
3190 seconds = parseInt(time);
3191 }
3192
3193 return seconds;
3194 },
3195
3196 getMediaSrcByQuality: function(ad, quality) {
3197 var medias = ad.getElementsByTagName('MediaFile'),
3198 mp4Medias = [],
3199 mp4MediasQualities = [],
3200 bestBiggerQuality = null;
3201
3202 if (medias.length) {
3203 __.each(medias, function(media) {
3204 if (media.getAttribute('type') == 'video/mp4') {
3205 var height = media.getAttribute('height');
3206
3207 mp4Medias[height] = media.textContent;
3208 }
3209 });
3210
3211 if (mp4Medias.length) {
3212 if(typeof mp4Medias[quality] !== 'undefined'){
3213 return String(mp4Medias[quality]).trim();
3214 } else {
3215 mp4MediasQualities = __.keys(mp4Medias);
3216 bestBiggerQuality = parseInt(mp4MediasQualities[mp4MediasQualities.length - 1]);
3217 quality = parseInt(quality);
3218
3219 __.each(mp4MediasQualities, function(mediaQuality, index) {
3220 mediaQuality = parseInt(mediaQuality);
3221
3222 // Get best bigger quality
3223 if((quality - mediaQuality) < 0 && Math.abs(quality - mediaQuality) <= Math.abs(quality - bestBiggerQuality)){
3224 bestBiggerQuality = mediaQuality;
3225 }
3226 });
3227
3228 return String(mp4Medias[bestBiggerQuality]).trim();
3229 }
3230 } else {
3231 this.reportError(403);
3232 return false;
3233 }
3234 } else {
3235 // Couldn’t find MediaFile that is supported by this video player,
3236 // based on the attributes of the MediaFile element.
3237 this.reportError(403);
3238 return false;
3239 }
3240 },
3241
3242 parseErrorTracking: function(root) {
3243 var error = root.getElementsByTagName('Error');
3244 if (error.length) {
3245 this.errorUrl = error[0].textContent || '';
3246 }
3247 },
3248
3249 parseImpressionTracking: function(ad, roll) {
3250 var impressionUrl = String(ad.getAttribute('impression') || '').trim(),
3251 defaultTrackUrl = this.playerSettings.htmlSettings.adsTrackUrl;
3252
3253 impressionUrl = (impressionUrl.indexOf('|') > -1) ? impressionUrl.split('|') : impressionUrl;
3254
3255 if (__.isArray(impressionUrl)) {
3256 roll.impressionUrl = impressionUrl;
3257 roll.impressionUrl.push(defaultTrackUrl);
3258 } else {
3259 roll.impressionUrl = [impressionUrl, defaultTrackUrl];
3260 }
3261 return roll;
3262 },
3263
3264 parseClickTracking: function(ad, roll, prefix) {
3265 var defaultTrackUrl = this.playerSettings.htmlSettings.adsTrackUrl,
3266 prefix = prefix || '',
3267 clickNodes = ad.getElementsByTagName(prefix + 'ClickThrough'),
3268 clickUrl = (clickNodes.length ? clickNodes[0].textContent : ''),
3269 customClickNodes = ad.getElementsByTagName(prefix + 'CustomClick'),
3270 clickTrackingNodes = [].slice.call(ad.getElementsByTagName(prefix + 'ClickTracking'));
3271
3272 if (customClickNodes.length ||
3273 clickTrackingNodes.length
3274 ) {
3275 if (!clickUrl) {
3276 clickUrl = '#'; // emulate url to be able to track clicks
3277 }
3278
3279 roll.clickTrackUrl = [];
3280
3281 if (customClickNodes.length) {
3282 roll.clickTrackUrl.push(String(customClickNodes[0].textContent).trim());
3283 }
3284
3285 if (clickTrackingNodes.length) {
3286 __.each(clickTrackingNodes, function(node) {
3287 roll.clickTrackUrl.push(String(node.textContent).trim());
3288 });
3289 }
3290 roll.clickTrackUrl.push(defaultTrackUrl);
3291 }
3292 roll.clickUrl = clickUrl;
3293
3294 return roll;
3295 },
3296
3297 parseTrackingEvents: function(ad) {
3298 var tracking = {},
3299 trackingNodes = ad.getElementsByTagName('Tracking');
3300
3301 __.each(trackingNodes, function(node) {
3302 var event = node.getAttribute('event'),
3303 url = node.textContent;
3304 if (event && __.isPath(url)) {
3305 if (__.isUndefined(tracking[event])) {
3306 tracking[event] = [url];
3307 } else {
3308 tracking[event].push(url);
3309 }
3310 }
3311
3312 });
3313
3314 return tracking;
3315 },
3316
3317 track: function(action) {
3318
3319 },
3320
3321 checkUnsupportedVastFeatures: function(root) {
3322 if (root.getElementsByTagName('Wrapper').length) {
3323 this.errorUnsupportedFeature('Wrapper', 300); // General Wrapper error.
3324 }
3325
3326 if (root.getElementsByTagName('Extension').length) {
3327 this.errorUnsupportedFeature('Extension');
3328 }
3329
3330 if (root.getElementsByTagName('AdVerifications').length ||
3331 root.getElementsByTagName('Verification').length
3332 ) {
3333 this.errorUnsupportedFeature('AdVerifications');
3334 }
3335
3336 if (root.getElementsByTagName('CompanionAds').length ||
3337 root.getElementsByTagName('Companion').length
3338 ) {
3339 this.errorUnsupportedFeature('CompanionAds', 600); // General CompanionAds error.
3340 }
3341 },
3342
3343 checkUnsupportedAdFeatures: function(ad) {
3344 if (parseInt(ad.getAttribute('sequence')) > 0) {
3345 this.errorUnsupportedFeature('Ad Pods');
3346 }
3347
3348 if (ad.getAttribute('conditionalAd')) {
3349 this.errorUnsupportedFeature('Conditional Ads');
3350 }
3351
3352 if (ad.getElementsByTagName('Icons').length ||
3353 ad.getElementsByTagName('Icon').length
3354 ) {
3355 this.errorUnsupportedFeature('Icon');
3356 }
3357 },
3358
3359 reportError: function(code) {
3360 if (!code) {
3361 code = 900; // Unidentified error
3362 }
3363 if (this.errorUrl) {
3364 __.ajaxLoader(this.errorUrl.replace('[ERRORCODE]', code));
3365 }
3366 // store last fired error code for debugging purposes
3367 this.errorCode = code;
3368 },
3369
3370 errorLoadingXml: function() {
3371 console.warn('VAST Parser: error loading XML file, player continues to work without "' + this.rollType + 'Roll" data');
3372 this.status = 'error';
3373 },
3374
3375 errorParsingXml: function() {
3376 console.warn('VAST Parser: error parsing XML file, player continues to work without "' + this.rollType + 'Roll" data');
3377 this.reportError(100); // XML parsing error
3378 this.status = 'error';
3379 },
3380
3381 errorUnsupportedFeature: function(featureName, code) {
3382 console.warn('VAST Parser: No "' + featureName + '" support yet');
3383 if (code) {
3384 this.reportError(code);
3385 }
3386 }
3387 }
3388};
3389(function(window, _) {
3390 'use strict';
3391
3392 var BufferedRanges = function(container, subscribeToEvent, s) {
3393
3394 var bufferedRanges = [],
3395 bufferedRangesInfo = [],
3396 bufferedZone;
3397
3398 function addBuffer(info, duration) {
3399 // make the copy of previous array
3400 var prevRanges = bufferedRangesInfo.slice(),
3401 ranges = [],
3402 range,
3403 rangeElement,
3404 i;
3405
3406 // converting TimeRanges to basic array
3407 for (i = 0; i < info.length; i++) {
3408 range = {
3409 start: (info.start(i) * 100 / duration),
3410 end: (info.end(i) * 100 / duration)
3411 }
3412
3413 // searching for active (being updated) buffered ranges
3414 if (prevRanges.length <= i ||
3415 prevRanges[i].start != range.start ||
3416 prevRanges[i].end != range.end
3417 ) {
3418 range.update = true;
3419 }
3420 ranges.push(range);
3421 }
3422
3423 // new range started
3424 if (ranges.length > prevRanges.length) {
3425
3426 rangeElement = s('.buffer');
3427 container.appendChild(rangeElement);
3428 bufferedRanges.push(rangeElement);
3429
3430 // new star was born!
3431 // some ranges collapsed into one
3432 } else if (prevRanges.length > ranges.length) {
3433 // remove active flags from all ranges at this moment
3434 // do not animate anything!
3435 for (i = 0; i < prevRanges.length; i++) {
3436 if (i >= ranges.length) {
3437 try {
3438 // need to delete previous element
3439 if(bufferedRanges[i]) {
3440 container.removeChild(bufferedRanges[i]);
3441 }
3442 } catch(error) {}
3443 } else {
3444 ranges[i].update = true;
3445 }
3446 }
3447 // cleanup empty holes in array
3448 bufferedRanges.splice(ranges.length);
3449 }
3450
3451 bufferedZone = ranges[ranges.length-1].end;
3452
3453 for (i = 0; i < ranges.length; i++) {
3454 range = ranges[i];
3455 // update dimensions
3456
3457 if (range.update && bufferedRanges[i]) {
3458 var width = range.end - range.start;
3459 // chrome buffering bug
3460 if (range.end > 98.5) {
3461 width = 100 - range.start;
3462 }
3463 bufferedRanges[i].style.left = range.start + '%';
3464 bufferedRanges[i].style.width = width + '%';
3465 }
3466 }
3467
3468 bufferedRangesInfo = ranges;
3469 }
3470
3471 (function listenPlayerEvents() {
3472 subscribeToEvent('onBuffer', function(i,e,o) {
3473 var info = o.buffered,
3474 duration = o.duration;
3475
3476 if (info.length && !__.isNaN(duration)) {
3477 addBuffer(info, duration);
3478 }
3479 });
3480 })();
3481
3482 return {
3483 getBuffered: function() {
3484 return {
3485 zone: bufferedZone,
3486 ranges: bufferedRangesInfo,
3487 elements: bufferedRanges
3488 }
3489 }
3490 }
3491 };
3492
3493 window.MHP1138 = window.MHP1138 || {};
3494 window.MHP1138.BufferedRanges = BufferedRanges;
3495})(window, __);
3496(function(window) {
3497 'use strict';
3498
3499 var chrome = window.chrome;
3500
3501 /** @const {number} Time in milliseconds for minimal progress update */
3502 var TIMER_STEP = 1000;
3503
3504 /** @const {number} Height, in pixels, of volume bar */
3505 var FULL_VOLUME_HEIGHT = 100;
3506
3507 /**
3508 * Constants of states for media playback
3509 * @enum {string}
3510 */
3511 var PLAYER_STATE = {
3512 IDLE: 'IDLE',
3513 LOADING: 'LOADING',
3514 LOADED: 'LOADED',
3515 PLAYING: 'PLAYING',
3516 PAUSED: 'PAUSED',
3517 STOPPED: 'STOPPED',
3518 ERROR: 'ERROR'
3519 };
3520
3521 /**
3522 * Cast player object
3523 * Main variables:
3524 * - PlayerHandler object for handling media playback
3525 * - Cast player variables for controlling Cast mode media playback
3526 * - Current media variables for transition between Cast and local modes
3527 * @struct @constructor
3528 */
3529 var CastPlayer = function(player, fireEvent) {
3530 /** @type {PlayerHandler} Delegation proxy for media playback */
3531 this.player = player;
3532 this.fireEvent = fireEvent;
3533 this.mediaUrl = '';
3534 this.seeking = false;
3535 this.playerHandler = new PlayerHandler(this);
3536 var self = this;
3537 this.castAvailable = false;
3538 this.castSession = '';
3539
3540 /** @type {PLAYER_STATE} A state for media playback */
3541 this.playerState = PLAYER_STATE.IDLE;
3542
3543 /* Cast player variables */
3544 /** @type {cast.framework.RemotePlayer} */
3545 this.remotePlayer = null;
3546 /** @type {cast.framework.RemotePlayerController} */
3547 this.remotePlayerController = null;
3548
3549 /** @type {number} A number for current media time */
3550 this.currentMediaTime = 0;
3551 /** @type {number} A number for current media duration */
3552 this.currentMediaDuration = -1;
3553 /** @type {?number} A timer for tracking progress of media */
3554 this.timer = null;
3555
3556 /** @type {function()} */
3557 this.incrementMediaTimeHandler = this.incrementMediaTime.bind(this);
3558
3559 if(window.chrome && chrome.cast && MHP1138.detector.isChrome()) {
3560 this.checkCastAvailability();
3561 }
3562 };
3563
3564 CastPlayer.prototype.checkCastAvailability = function() {
3565 var self = this;
3566 if(chrome.cast.isAvailable) {
3567 this.castAvailable = chrome.cast.isAvailable;
3568 if(!this.player.preRoll.enabled) {
3569 this.initializeCastPlayer();
3570 }
3571 } else {
3572 setTimeout(function() {
3573 self.checkCastAvailability();
3574 },1000);
3575 }
3576 };
3577
3578 CastPlayer.prototype.initializeCastPlayer = function() {
3579
3580 var options = {};
3581
3582 // Set the receiver application ID to your own (created in the
3583 // Google Cast Developer Console), or optionally
3584 // use the chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
3585 options.receiverApplicationId = chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;
3586
3587 // Auto join policy can be one of the following three:
3588 // ORIGIN_SCOPED - Auto connect from same appId and page origin
3589 // TAB_AND_ORIGIN_SCOPED - Auto connect from same appId, page origin, and tab
3590 // PAGE_SCOPED - No auto connect
3591 options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.PAGE_SCOPED;
3592
3593 cast.framework.CastContext.getInstance().setOptions(options);
3594
3595 //hide show cast button depending on target availability
3596 this.remotePlayer = new cast.framework.RemotePlayer();
3597 this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
3598 this.remotePlayerController.addEventListener(
3599 cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
3600 this.switchPlayer.bind(this)
3601 );
3602 this.fireEvent('chromecastAvailable', { available: false });
3603 };
3604
3605 /*
3606 * PlayerHandler and setup functions
3607 */
3608 CastPlayer.prototype.switchPlayer = function() {
3609 this.stopProgressTimer();
3610 this.playerState = PLAYER_STATE.IDLE;
3611 var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
3612 this.castSession = castSession;
3613 if (cast && cast.framework) {
3614 if (this.remotePlayer.isConnected && castSession) {
3615 this.fireEvent('chromecastAvailable', { available: true });
3616 this.setupRemotePlayer(castSession);
3617 } else {
3618 this.stopSession();
3619 }
3620 return;
3621 }
3622 };
3623
3624 /**
3625 * Set the PlayerHandler target to use the remote player
3626 */
3627 CastPlayer.prototype.setupRemotePlayer = function (castSession) {
3628 // Add event listeners for player changes which may occur outside sender app
3629 this.remotePlayerController.addEventListener(
3630 cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
3631 function() {
3632 if (this.remotePlayer.isPaused) {
3633 this.playerHandler.pause();
3634 } else {
3635 this.playerHandler.play();
3636 }
3637 }.bind(this)
3638 );
3639
3640 this.remotePlayerController.addEventListener(
3641 cast.framework.RemotePlayerEventType.IS_MUTED_CHANGED,
3642 function() {
3643 if (this.remotePlayer.isMuted) {
3644 this.playerHandler.mute();
3645 } else {
3646 this.playerHandler.unMute();
3647 }
3648 }.bind(this)
3649 );
3650
3651 this.remotePlayerController.addEventListener(
3652 cast.framework.RemotePlayerEventType.VOLUME_LEVEL_CHANGED,
3653 function() {
3654 var newVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
3655 this.player.volume = newVolume;
3656 }.bind(this)
3657 );
3658
3659 // This object will implement PlayerHandler callbacks with
3660 // remotePlayerController, and makes necessary UI updates specific
3661 // to remote playback
3662 var playerTarget = {};
3663
3664 playerTarget.play = function () {
3665 if (this.remotePlayer.isPaused) {
3666 this.remotePlayerController.playOrPause();
3667 }
3668 }.bind(this);
3669
3670 playerTarget.pause = function () {
3671 if (!this.remotePlayer.isPaused) {
3672 this.remotePlayerController.playOrPause();
3673 }
3674 }.bind(this);
3675
3676 playerTarget.stop = function () {
3677 castSession.endSession(true);
3678 }.bind(this);
3679
3680 playerTarget.load = function () {
3681 this.mediaUrl = this.player.videoSources[this.player.selectedResolution].videoUrl;
3682 var mediaInfo = new chrome.cast.media.MediaInfo(this.mediaUrl);
3683
3684 mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
3685 mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;
3686 mediaInfo.metadata.title = this.player.settings.mainRoll.title;
3687 mediaInfo.metadata.subtitle = this.player.selectedResolution + 'p';
3688 mediaInfo.metadata.images = [{'url': this.player.settings.mainRoll.poster }];
3689
3690 var request = new chrome.cast.media.LoadRequest(mediaInfo);
3691
3692 /**
3693 * Show spinner before init
3694 */
3695 this.fireEvent('onWaiting');
3696
3697 /**
3698 * Loads media and depnding on the success or not, will return appropriate response
3699 *
3700 * @param {object} request - Request object containing the information about the media
3701 * @param {function} sucessCallback - Callback function for when the media has been properly loaded
3702 * @param {function} failureCallback - Callback function for when the media fails to load
3703 */
3704
3705 castSession.loadMedia(request).then(
3706 this.playerHandler.loaded.bind(this.playerHandler),
3707 function (errorCode) {
3708 this.playerState = PLAYER_STATE.ERROR;
3709 console.log('Remote media load error: ' + this.getErrorMessage(errorCode));
3710 }.bind(this));
3711
3712 }.bind(this);
3713
3714 playerTarget.getCurrentMediaTime = function() {
3715 return this.remotePlayer.currentTime;
3716 }.bind(this);
3717
3718 playerTarget.getMediaDuration = function() {
3719 return this.remotePlayer.duration;
3720 }.bind(this);
3721
3722 playerTarget.updateDisplayMessage = function () {
3723 console.log(this.playerState + ' on ' + castSession.getCastDevice().friendlyName);
3724 }.bind(this);
3725
3726 playerTarget.mute = function () {
3727 if (!this.remotePlayer.isMuted) {
3728 this.remotePlayerController.muteOrUnmute();
3729 }
3730 }.bind(this);
3731
3732 playerTarget.unMute = function () {
3733 if (this.remotePlayer.isMuted) {
3734 this.remotePlayerController.muteOrUnmute();
3735 }
3736 }.bind(this);
3737
3738 playerTarget.isMuted = function() {
3739 return this.remotePlayer.isMuted;
3740 }.bind(this);
3741
3742 playerTarget.seekTo = function (time) {
3743 this.remotePlayer.currentTime = time;
3744 this.remotePlayerController.seek();
3745 }.bind(this);
3746
3747 this.playerHandler.setTarget(playerTarget);
3748
3749 // Setup remote player volume right on setup
3750 // The remote player may have had a volume set from previous playback
3751 if (this.remotePlayer.isMuted) {
3752 this.playerHandler.mute();
3753 }
3754 var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
3755 this.player.volume = currentVolume;
3756
3757 this.playerHandler.play();
3758 };
3759
3760 CastPlayer.prototype.setActiveState = function(flag) {
3761 this.fireEvent('onCasting', { chromecast: flag });
3762 this.active = flag;
3763 };
3764
3765 CastPlayer.prototype.stopSession = function() {
3766 this.pause();
3767 this.setActiveState(false);
3768 this.endPlayback();
3769 this.currentMediaTime = 0;
3770 this.stopProgressTimer();
3771 this.playerState = PLAYER_STATE.IDLE;
3772 this.playerHandler.updateDisplayMessage();
3773 this.player.seek(this.player.currentTime, false);
3774 this.fireEvent('onSeek');
3775 this.playerHandler.stop();
3776 };
3777
3778 /**
3779 * End playback. Called when media ends.
3780 */
3781 CastPlayer.prototype.endPlayback = function() {
3782 this.player.playerElement.load();
3783 };
3784
3785 CastPlayer.prototype.seek = function(seekTime, playAfter) {
3786 this.seeking = true;
3787 this.fireEvent('onSeek');
3788 this.playerHandler.seekTo(seekTime);
3789 this.player.updateCurrentTime(this.remotePlayer.currentTime);
3790 this.playerHandler.play();
3791 setTimeout(function() {
3792 this.seeking = false;
3793 }, 500);
3794 };
3795
3796 CastPlayer.prototype.play = function() {
3797 this.playerHandler.play();
3798 };
3799
3800 CastPlayer.prototype.pause = function() {
3801 this.playerHandler.pause();
3802 };
3803
3804 /**
3805 * Starts the timer to increment the media progress bar
3806 */
3807 CastPlayer.prototype.startProgressTimer = function() {
3808 this.stopProgressTimer();
3809
3810 // Start progress timer
3811 this.timer = setInterval(this.incrementMediaTimeHandler, TIMER_STEP);
3812 };
3813
3814 /**
3815 * Stops the timer to increment the media progress bar
3816 */
3817 CastPlayer.prototype.stopProgressTimer = function() {
3818 if (this.timer) {
3819 clearInterval(this.timer);
3820 this.timer = null;
3821 }
3822 };
3823
3824 /**
3825 * Helper function
3826 * Increment media current position by 1 second
3827 */
3828 CastPlayer.prototype.incrementMediaTime = function() {
3829 // First sync with the current player's time
3830 this.currentMediaTime = this.playerHandler.getCurrentMediaTime();
3831 this.currentMediaDuration = this.playerHandler.getMediaDuration();
3832
3833 if (this.playerState === PLAYER_STATE.PLAYING) {
3834 if (this.currentMediaTime < this.currentMediaDuration) {
3835 this.currentMediaTime += 1;
3836 this.player.updateCurrentTime(this.currentMediaTime);
3837 } else {
3838 this.stopSession();
3839 }
3840 }
3841 };
3842
3843
3844 /**
3845 * PlayerHandler
3846 *
3847 * This is a handler through which the application will interact
3848 * with both the RemotePlayer and LocalPlayer. Combining these two into
3849 * one interface is one approach to the dual-player nature of a Cast
3850 * Chrome application. Otherwise, the state of the RemotePlayer can be
3851 * queried at any time to decide whether to interact with the local
3852 * or remote players.
3853 *
3854 * To set the player used, implement the following methods for a target object
3855 * and call setTarget(target).
3856 *
3857 * Methods to implement:
3858 * - play()
3859 * - pause()
3860 * - stop()
3861 * - seekTo(time)
3862 * - load(mediaIndex)
3863 * - getMediaDuration()
3864 * - getCurrentMediaTime()
3865 * - setVolume(volumeSliderPosition)
3866 * - mute()
3867 * - unMute()
3868 * - isMuted()
3869 * - updateDisplayMessage()
3870 */
3871 var PlayerHandler = function(castPlayer) {
3872 this.target = {};
3873
3874 this.setTarget= function(target) {
3875 this.target = target;
3876 };
3877
3878 this.play = function() {
3879 if (castPlayer.playerState !== PLAYER_STATE.PLAYING &&
3880 castPlayer.playerState !== PLAYER_STATE.PAUSED &&
3881 castPlayer.playerState !== PLAYER_STATE.LOADED) {
3882 this.load();
3883 return;
3884 }
3885
3886 this.target.play();
3887 castPlayer.playerState = PLAYER_STATE.PLAYING;
3888 // do not fire play / pause events while seeking
3889 if (this.seeking) return;
3890
3891 castPlayer.player.seeking = false;
3892 castPlayer.player.playing = true;
3893 castPlayer.fireEvent('onPlay');
3894 castPlayer.videoChange = false;
3895 this.updateDisplayMessage();
3896 };
3897
3898 this.pause = function() {
3899 if (castPlayer.playerState !== PLAYER_STATE.PLAYING) {
3900 return;
3901 }
3902 // do not fire play / pause events while seeking
3903 if (this.seeking) return;
3904 // do not react on paused events while changing media stream
3905 // the cake is a lie
3906 if (this.videoChange) return;
3907
3908 castPlayer.player.playing = false;
3909 this.target.pause();
3910 castPlayer.fireEvent('onPause');
3911 castPlayer.playerState = PLAYER_STATE.PAUSED;
3912 this.updateDisplayMessage();
3913 };
3914
3915 this.stop = function() {
3916 this.target.stop();
3917 castPlayer.playerState = PLAYER_STATE.STOPPED;
3918 this.updateDisplayMessage();
3919 };
3920
3921 this.load = function() {
3922 castPlayer.playerState = PLAYER_STATE.LOADING;
3923 this.target.load();
3924 this.updateDisplayMessage();
3925 };
3926
3927 this.loaded = function() {
3928 castPlayer.setActiveState(true);
3929 castPlayer.currentMediaDuration = this.getMediaDuration();
3930 castPlayer.playerState = PLAYER_STATE.LOADED;
3931 if (castPlayer.currentMediaTime > 0) {
3932 this.seekTo(castPlayer.currentMediaTime);
3933 }
3934 this.play();
3935 castPlayer.startProgressTimer();
3936 this.updateDisplayMessage();
3937 };
3938
3939 this.getCurrentMediaTime = function() {
3940 return this.target.getCurrentMediaTime();
3941 };
3942
3943 this.getMediaDuration = function() {
3944 return this.target.getMediaDuration();
3945 };
3946
3947 this.updateDisplayMessage = function () {
3948 this.target.updateDisplayMessage();
3949 }
3950
3951 this.mute = function() {
3952 this.target.mute();
3953 };
3954
3955 this.unMute = function() {
3956 this.target.unMute();
3957 };
3958
3959 this.isMuted = function() {
3960 return this.target.isMuted();
3961 };
3962
3963 this.seekTo = function(time) {
3964 this.target.seekTo(time);
3965 this.updateDisplayMessage();
3966 };
3967 };
3968
3969 /**
3970 * Makes human-readable message from chrome.cast.Error
3971 * @param {chrome.cast.Error} error
3972 * @return {string} error message
3973 */
3974 CastPlayer.prototype.getErrorMessage = function(error) {
3975 this.setActiveState(false);
3976 switch (error.code) {
3977 case chrome.cast.ErrorCode.API_NOT_INITIALIZED:
3978 return 'The API is not initialized.' +
3979 (error.description ? ' :' + error.description : '');
3980 case chrome.cast.ErrorCode.CANCEL:
3981 return 'The operation was canceled by the user' +
3982 (error.description ? ' :' + error.description : '');
3983 case chrome.cast.ErrorCode.CHANNEL_ERROR:
3984 return 'A channel to the receiver is not available.' +
3985 (error.description ? ' :' + error.description : '');
3986 case chrome.cast.ErrorCode.EXTENSION_MISSING:
3987 return 'The Cast extension is not available.' +
3988 (error.description ? ' :' + error.description : '');
3989 case chrome.cast.ErrorCode.INVALID_PARAMETER:
3990 return 'The parameters to the operation were not valid.' +
3991 (error.description ? ' :' + error.description : '');
3992 case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:
3993 return 'No receiver was compatible with the session request.' +
3994 (error.description ? ' :' + error.description : '');
3995 case chrome.cast.ErrorCode.SESSION_ERROR:
3996 return 'A session could not be created, or a session was invalid.' +
3997 (error.description ? ' :' + error.description : '');
3998 case chrome.cast.ErrorCode.TIMEOUT:
3999 return 'The operation timed out.' +
4000 (error.description ? ' :' + error.description : '');
4001 }
4002 };
4003
4004
4005
4006 window.MHP1138 = window.MHP1138 || {};
4007 window.MHP1138.CastPlayer = CastPlayer;
4008})(window);
4009(function(window, _) {
4010 'use strict';
4011
4012 /**
4013 * Create screenshots from the video
4014 *
4015 * @param {object} settings seekPreview section from global config
4016 * @param {HTMLElement} videoTag html5 <video> tag
4017 * @param {HTMLElement} container container to create new canvas element
4018 * @param {function} getThumbnail false will disable screenshots from thumbnails (onSeek)
4019 * @param {function} getBufferedZone returns object with buffered ranges. { zone: 100 } will disable screenshots onSeek
4020 * @param {function} subscribeToEvent
4021 * @param {function} s satisfy shorthand
4022 */
4023
4024 var CanvasScreenshots = function(settings, videoTag, container, getThumbnail, getBufferedZone, subscribeToEvent, s) {
4025 var screenshot = s('.screenshot'),
4026 canvas = document.createElement('canvas');
4027
4028 screenshot.appendChild(canvas);
4029 container.appendChild(screenshot);
4030 hide();
4031
4032 function show() {
4033 _.removeClass(screenshot, 'hidden');
4034 }
4035
4036 function hide() {
4037 _.addClass(screenshot, 'hidden');
4038 }
4039
4040 function setBlur(value) {
4041 var blur = '';
4042
4043 if (value > 0) {
4044 blur = 'blur(' + parseInt(value) + 'px)';
4045 }
4046 canvas.style.filter = blur;
4047 canvas.style.mozFilter = blur;
4048 canvas.style.webkitFilter = blur;
4049 }
4050
4051 function take() {
4052 var videoAspect = videoTag.videoWidth / videoTag.videoHeight,
4053
4054 context = canvas.getContext('2d'),
4055 canvasWidth = canvas.clientWidth,
4056 canvasHeight = canvas.clientHeight,
4057 canvasAspect = canvasWidth / canvasHeight,
4058
4059 // initial values, will be updated
4060 clipWidth = canvasWidth,
4061 clipHeight = canvasHeight,
4062 x = 0,
4063 y = 0;
4064
4065 canvas.width = canvasWidth;
4066 canvas.height = canvasHeight;
4067
4068 if (canvasAspect < videoAspect) {
4069 clipHeight = canvasWidth / videoAspect;
4070 y = (canvasHeight - clipHeight) / 2;
4071 } else {
4072 clipWidth = canvasHeight * videoAspect;
4073 x = (canvasWidth - clipWidth) / 2;
4074 }
4075
4076 context.drawImage(videoTag, x, y, clipWidth, clipHeight);
4077 setBlur(0);
4078 show();
4079 }
4080
4081 function takeFromThumbnails(seconds) {
4082 if (!getThumbnail) return;
4083
4084 var preloadedThumbnail = getThumbnail(seconds),
4085 thumbnail, sheet;
4086
4087 // check if thumbnail sheet was fully loaded
4088 if (!preloadedThumbnail) {
4089 return false;
4090 } else {
4091 thumbnail = preloadedThumbnail.thumbnail;
4092 sheet = preloadedThumbnail.sheet;
4093 }
4094
4095 var thumbWidth = sheet.thumbWidth,
4096 thumbHeight = sheet.thumbHeight,
4097 thumbAspect = thumbWidth / thumbHeight,
4098
4099 context = canvas.getContext('2d'),
4100 canvasWidth = screenshot.clientWidth,
4101 canvasHeight = screenshot.clientHeight,
4102 canvasAspect = canvasWidth / canvasHeight,
4103
4104 // initial values, will be updated
4105 clipWidth = canvasWidth,
4106 clipHeight = canvasHeight,
4107 x = 0,
4108 y = 0,
4109 videoRatio = videoTag.videoWidth / videoTag.videoHeight, // Ratio of the video's intrisic dimensions
4110 realWidth = videoTag.offsetWidth,// The width and height of the video element
4111 realHeight = videoTag.offsetHeight,
4112 elementRatio = realWidth/realHeight; // The ratio of the element's width to its height
4113
4114 if (elementRatio > videoRatio) {
4115 realWidth = realHeight * videoRatio; // If the video element is short and wide
4116 }
4117
4118 canvas.width = canvasWidth;
4119 canvas.height = canvasHeight;
4120
4121 if (canvasAspect < thumbAspect) {
4122 clipHeight = canvasWidth / thumbAspect;
4123 y = (canvasHeight - clipHeight) / 2;
4124 } else {
4125 clipWidth = realWidth;//canvasHeight * thumbAspect;
4126 x = (canvasWidth - clipWidth) / 2;
4127 }
4128
4129 var thumbX = parseInt(thumbnail.cssLeft) * -1,
4130 thumbY = parseInt(thumbnail.cssTop) * -1;
4131
4132 context.drawImage(sheet.image, thumbX, thumbY, thumbWidth, thumbHeight, x, y, clipWidth, clipHeight);
4133 // add opacity animation and blur on top of 160x90 thumbnail image to hide JPEG artifacts
4134
4135 setBlur(settings.blur);
4136 show();
4137 }
4138
4139 function listenPlayerEvents() {
4140 var playerChangingQuality = false,
4141 hideAndResetFlag = function() {
4142 hide();
4143 playerChangingQuality = false;
4144 };
4145
4146 subscribeToEvent('onPlay', hideAndResetFlag);
4147 subscribeToEvent('onPause', hideAndResetFlag);
4148 subscribeToEvent('onEnd', hideAndResetFlag);
4149
4150
4151 subscribeToEvent('onQualityChange', function() {
4152 playerChangingQuality = true;
4153 take();
4154 });
4155
4156 subscribeToEvent('onSeek', function(i,e,o) {
4157 // no need to show preview
4158 // see TFE-330
4159 if (settings.showInBufferedZone == false && typeof getBufferedZone == 'function') {
4160 var buffered = getBufferedZone();
4161 if (buffered && buffered.zone > o.to / o.duration * 100) {
4162 return;
4163 }
4164 }
4165
4166 if (!playerChangingQuality) {
4167 takeFromThumbnails(o.to);
4168 }
4169 });
4170 }
4171
4172 listenPlayerEvents();
4173
4174 return {
4175 show: show,
4176 hide: hide,
4177 setBlur: setBlur,
4178 take: take,
4179 takeFromThumbnails: takeFromThumbnails
4180 }
4181 };
4182
4183 window.MHP1138 = window.MHP1138 || {};
4184 window.MHP1138.CanvasScreenshots = CanvasScreenshots;
4185})(window, __);
4186(function(window, _) {
4187 'use strict';
4188
4189 /**
4190 * Adds keyboard shortcuts to the player
4191 *
4192 * @param {MHP1138.HTML5Player} player
4193 * @param {mhp1138_skinBlueprint_default} skin
4194 * @param {function} fireEvent Function to fire local player events (starts from 'onXXX...')
4195 */
4196 var Keyboard = function(player, skin, fireEvent) {
4197
4198 // key codes and function names to call
4199 var shortcuts = {
4200 32: 'playPause', // space
4201 38: 'volumeUp', // arrow up
4202 40: 'volumeDown', // arrow down
4203 39: 'jumpForward', // arrow right
4204 37: 'jumpBackward' // arrow left
4205 },
4206
4207 // 0..9 keys seek to 0%..90% of video
4208 // "special" case as I dont wanna make 10 methods for them
4209 jumpMinKey = 48, // 0
4210 jumpMaxKey = 57, // 9
4211
4212 actions = {
4213 playPause: function() {
4214 player.togglePlayPause();
4215 },
4216 volumeUp: function() {
4217 player.setVolume(player.volume + 10);
4218 },
4219 volumeDown: function() {
4220 player.setVolume(player.volume - 10);
4221 },
4222 jumpForward: function() {
4223 if (!player.duration) return false;
4224 if (player.preRoll.enabled) return false;
4225 skin.moveSeekBarHandle(1);
4226 },
4227 jumpBackward: function() {
4228 if (!player.duration) return false;
4229 if (player.preRoll.enabled) return false;
4230 skin.moveSeekBarHandle(-1);
4231 },
4232 jumpToPercent: function(percentage) {
4233 if (!player.duration) return false;
4234 player.seek(player.duration / 100 * percentage, true);
4235 }
4236 };
4237
4238 // PRIVATES
4239
4240 function onKeydown(e) {
4241 if (!player.focused) return false;
4242
4243 var keyCode = e.keyCode,
4244 action = shortcuts[keyCode],
4245 params;
4246
4247 // [0..9] keys
4248 if (keyCode >= jumpMinKey &&
4249 keyCode <= jumpMaxKey
4250 ) {
4251 params = (keyCode - jumpMinKey) * 10;
4252 action = 'jumpToPercent';
4253 }
4254
4255 if (action) {
4256 actions[action](params);
4257 fireEvent('onKeyboard', { action: action });
4258 // Users dont want to scroll the page by 'space' or arrows
4259 // while watching our vids
4260 e.stopPropagation();
4261 e.preventDefault();
4262 return false;
4263 }
4264 }
4265
4266 function onKeyup() {
4267 if (!player.focused) return false;
4268 // skin.moveSeekBarHandle sets manualSeek flag to true,
4269 // we need to check if this keyUp is the part of
4270 // previously called jumpForward/jumpBackward on keyDown event
4271 if (skin.manualSeek) {
4272 skin.seekToNewPosition();
4273 }
4274 }
4275
4276 function bindShortcuts() {
4277 // TODO: fix keydown space mozilla bug
4278 document.addEventListener('keydown', onKeydown);
4279 document.addEventListener('keyup', onKeyup);
4280 }
4281
4282 function trackFocus() {
4283 // If the player is being clicked in any place, we tell the player it's been clicked
4284 // use skin click wrapper
4285 skin.addClickEvent(skin.container, function() {
4286 // cant stop bubblin of mousedown/touchend events at this point,
4287 // as document SHOULD receive them to support seekbar and volumebar drag
4288 // I delay flag set up (changin execution context via setTimeout(0))
4289 // AFTER document event handler
4290 setTimeout(function() {
4291 getFocused();
4292 }, 0);
4293 });
4294
4295 // one more option to get focus for autoplayed vids
4296
4297 // cant use 'mouseover' because you should have the ability
4298 // to scroll thru the player via keyboard without touching the mouse and dont get focused
4299 skin.container.addEventListener('mousemove', function() {
4300 getFocused();
4301 });
4302
4303 // If anything but the player is clicked
4304 document.body.addEventListener('click', function() {
4305 // cancel focus for all players on the page
4306 cancelFocus('');
4307 });
4308 }
4309
4310 function getFocused() {
4311 if (!player.focused) {
4312 player.focused = true;
4313 cancelFocus(player.playerId);
4314 }
4315 }
4316
4317 // cancels focus for all players except ID
4318 function cancelFocus(id) {
4319 var players = window.MHP1138.inspect();
4320 _.each(players, function(value, key) {
4321 if (key != id) {
4322 value.player.focused = false;
4323 }
4324 });
4325 }
4326
4327
4328 // CONSTRUCTOR
4329
4330 bindShortcuts();
4331 trackFocus();
4332 };
4333
4334 window.MHP1138 = window.MHP1138 || {};
4335 window.MHP1138.Keyboard = Keyboard;
4336})(window, __);
4337(function(window, _) {
4338 'use strict';
4339
4340 var WatchHDButton = function(playerContainer, player, logoUrl, addClickEvent, s, l) {
4341 var btn = s('.watchHD');
4342
4343 btn.innerHTML = l('%WATCH_HD%');
4344
4345 playerContainer.appendChild(btn);
4346 addClickEvent(btn, function(e) {
4347 e.stopPropagation();
4348 e.preventDefault();
4349
4350 var url = player.addUTM(player.addCurrentTimeToUrl(logoUrl), 'embed', 'embed-hd-html5');
4351 player.pause();
4352 player.openRedirectWindow(url);
4353 });
4354
4355 return btn;
4356 };
4357
4358 window.MHP1138 = window.MHP1138 || {};
4359 window.MHP1138.WatchHDButton = WatchHDButton;
4360})(window, __);
4361(function(window, _) {
4362 'use strict';
4363 // We have extended underscore to "double-underscore", but the module shouldnt know about it,
4364 // using its basic methods such as .each
4365
4366 /**
4367 * Adds fullscreen support to the player
4368 *
4369 * @param {MHP1138.HTML5Player} player
4370 * @param {function} fireEvent Function to fire local player events (starts from 'onXXX...')
4371 * @param {function} subscribeToEvent custom event handler from the player package
4372 * @param {boolean} ios iOS flag from detector
4373 */
4374 var Fullscreen = function(player, fireEvent, subscribeToEvent, ios) {
4375 var doc = window.document,
4376 playerId = player.playerId;
4377
4378 // list of external player events to exit fullscreen (if entered)
4379 var exitEvents = ['collapsePlayer', 'expandPlayer', 'onShare', 'onRedirect'];
4380 // fullscreen events to listen
4381 var fullscreenEvents = ['webkitfullscreenchange', 'mozfullscreenchange', 'MSFullscreenChange', 'fullscreenchange'];
4382 var fullscreenState = false;
4383
4384 function checkAvailability() {
4385 var element = doc.documentElement,
4386 elementIos = player.playerElement;//IOS contains webkitSupportsFullscreen in video element
4387 if (element.requestFullScreen ||
4388 element.mozRequestFullScreen ||
4389 element.webkitRequestFullScreen ||
4390 element.msRequestFullscreen ||
4391 elementIos.webkitEnterFullscreen
4392 ) {
4393 return true;
4394 }
4395 return false;
4396 }
4397
4398 function enterFullscreen() {
4399 var element = player.playerContainerElement;
4400
4401 if (element.requestFullScreen) {
4402 element.requestFullScreen();
4403 } else if (element.mozRequestFullScreen) {
4404 element.mozRequestFullScreen();
4405 } else if (element.webkitRequestFullScreen) {
4406 element.webkitRequestFullScreen();
4407 } else if (element.msRequestFullscreen) {
4408 element.msRequestFullscreen();
4409
4410 // special case for iOS
4411 } else if (ios && !element.webkitRequestFullScreen) {
4412 // assuming we would find a video tag inside player container
4413 var video = player.playerElement;
4414
4415 // there is a different method name to enter fullscreen
4416 if (video.webkitSupportsFullscreen) {
4417 video.webkitEnterFullscreen();
4418 }
4419 }
4420 }
4421
4422 function exitFullscreen() {
4423 if (doc.cancelFullScreen) {
4424 doc.cancelFullScreen();
4425 } else if (doc.mozCancelFullScreen) {
4426 doc.mozCancelFullScreen();
4427 } else if (doc.webkitCancelFullScreen) {
4428 doc.webkitCancelFullScreen();
4429 } else if (doc.msExitFullscreen) {
4430 doc.msExitFullscreen();
4431 }
4432 }
4433
4434 function toggleFullscreen() {
4435 if (fullscreenState) {
4436 exitFullscreen();
4437 } else {
4438 enterFullscreen();
4439 }
4440 }
4441
4442 function listenChangeEvents() {
4443 function fullscreenChanged() {
4444 var element = doc.fullscreenElement ||
4445 doc.webkitFullscreenElement ||
4446 doc.mozFullScreenElement ||
4447 doc.msFullscreenElement ||
4448 null;
4449
4450 if (_.isNull(element)) {
4451 if (fullscreenState) {
4452 fullscreenState = false;
4453 fireEvent('onFullscreen', { fullscreen: false });
4454 }
4455 } else { // fullscreenElement is exists
4456 if (element.id == playerId) {
4457 fullscreenState = true;
4458 fireEvent('onFullscreen', { fullscreen: true });
4459 }
4460 }
4461 }
4462
4463 _.each(fullscreenEvents, function(eventName) {
4464 doc.addEventListener(eventName, fullscreenChanged);
4465 });
4466 }
4467
4468 function listenPlayerEvents() {
4469 _.each(exitEvents, function(eventName) {
4470 subscribeToEvent(eventName, exitFullscreen);
4471 });
4472 }
4473
4474 if (checkAvailability()) {
4475 listenChangeEvents();
4476 listenPlayerEvents();
4477
4478 return {
4479 enabled: true,
4480 enter: enterFullscreen,
4481 exit: exitFullscreen,
4482 toggle: toggleFullscreen
4483 };
4484 } else {
4485 return {
4486 enabled: false
4487 };
4488 }
4489 };
4490
4491 window.MHP1138 = window.MHP1138 || {};
4492 window.MHP1138.Fullscreen = Fullscreen;
4493})(window, __);
4494function mhp1138_skin() {
4495 var l; // shortcut for 'localize' method
4496 var ss = function(selector) {
4497 selector = selector.replace(/\.(\S+?)/g, ".mhp1138_$1");
4498 return satisfy(selector);
4499 };
4500 var s = function(selector) {
4501 return ss(selector)[0];
4502 };
4503
4504 var subscribeToEvent,
4505 fireEvent,
4506 // shortcuts for the most used underscore functions
4507 addClass = __.addClass,
4508 removeClass = __.removeClass,
4509 xest = __.xest,
4510 each = __.each,
4511 isPath = __.isPath,
4512 isTablet = MHP1138.detector.isTablet(),
4513 isIos = MHP1138.detector.isIos();
4514
4515 return {
4516 playerState: 'buffering',
4517 hiddenControls: true, // initial player state
4518 // TODO: hardcoded value, need to push it to initial config
4519 mousePosition: {},
4520 tooltipMinimalBounds: 5,
4521 doubleClickInterval: 300, // ms
4522
4523 //INIT THE SKIN
4524 init: function(player, callback) {
4525 var self = this,
4526 settings = player.settings;
4527
4528 this.player = player;
4529 this.settings = settings;
4530 this.container = player.playerContainerElement;
4531 // shortcut
4532 l = player.l10n.localize;
4533
4534 // localizing + proxifying global function
4535 subscribeToEvent = function(eventName, callback) {
4536 return MHP1138.player.subscribeToEvent(eventName, player.playerId, callback);
4537 }
4538
4539 fireEvent = function(eventName, params) {
4540 return __.fireEvent(player, eventName, params);
4541 }
4542
4543 this.setPlayerState('buffering');
4544 this.subscribeToPlayerEvents();
4545
4546 this.initButtonHoversOnTouch();
4547
4548 this.initEventCatcher();
4549 this.initTimeLabels();
4550 this.initPlaybackControls();
4551 this.initNextVideoBtn();
4552 this.initVolumeBar();
4553 this.initFullscreenBtn();
4554 this.initChromecastBtn();
4555 this.initCinemaModeBtn();
4556 this.initThumbnails();
4557 this.initLogo();
4558 this.initSeekBar();
4559 this.initTopBar();
4560 this.initShareBtn();
4561 this.initTooltips();
4562 this.initContextMenu();
4563 this.initAutoHideControls();
4564
4565 this.createQualityMenu();
4566 if (settings.hotspots.enabled) {
4567 this.createHotspotsBtn();
4568 this.createHotspotsGraph();
4569 }
4570 this.createSlowMotionBtn();
4571 this.createAutoplayBtn();
4572 this.createGrid();
4573
4574 this.filterFeatures(settings.features);
4575
4576
4577 // if (MHP1138.ThumbnailsController &&
4578 // player.thumbnails
4579 // ) {
4580 // this.thumbnailsController = new MHP1138.ThumbnailsController(
4581 // this.container, // player container
4582 // this.elements.thumbnails, // thumbnails markup selectors
4583 // subscribeToEvent, // method to subscribe on player events
4584 // player.thumbnails.get // method to retrieve thumbnail info
4585 // );
4586 // }
4587
4588 if (MHP1138.BufferedRanges) {
4589 this.bufferedRanges = new MHP1138.BufferedRanges(
4590 this.seekBarBufferElement,
4591 subscribeToEvent,
4592 s
4593 );
4594 }
4595
4596 if (MHP1138.CanvasScreenshots &&
4597 settings.seekPreview.enabled &&
4598 !settings.isVr && // do not take shots from VR videos
4599 player.thumbnails // thumbnailsLoader was initialized in the player core
4600 ) {
4601 this.screenshots = new MHP1138.CanvasScreenshots(
4602 settings.seekPreview,
4603 player.playerElement, // video tag
4604 player.videoWrapper, // video tag wrapper
4605 player.thumbnails.get,
4606 this.bufferedRanges.getBuffered || false,
4607 subscribeToEvent,
4608 s
4609 );
4610 }
4611
4612 var embedsSettings = settings.embeds;
4613 if (MHP1138.WatchHDButton &&
4614 embedsSettings.enabled &&
4615 embedsSettings.watchHD
4616 ) {
4617 this.watchHDBtn = new MHP1138.WatchHDButton(
4618 this.container,
4619 player,
4620 embedsSettings.redirect.logoUrl,
4621 this.addClickEvent,
4622 s,
4623 l
4624 );
4625 }
4626
4627 callback();
4628 },
4629
4630 initLogo: function() {
4631 var player = this.player,
4632 logoTemplate = xest(
4633 '#mhp1138_skin' +
4634 ' .mhp1138_logo_' + this.settings.quickSetup
4635 ),
4636 embeds = this.settings.embeds,
4637 logoUrl = embeds.redirect.logoUrl;
4638
4639 this.logo = xest(this.elements.controls.logo);
4640
4641 if (!__.isUndefined(logoTemplate)) {
4642 this.logo.innerHTML = logoTemplate.innerHTML;
4643 }
4644
4645 if (isPath(logoUrl)) {
4646 addClass(this.logo, 'isLink');
4647
4648 this.addClickEvent(this.logo, function() {
4649 var url = player.addCurrentTimeToUrl(logoUrl);
4650 if (embeds.enabled && embeds.utmRedirect.logo) {
4651 url = player.addUTM(url, 'embed', 'embed-logo-html5');
4652 }
4653
4654 player.pause();
4655 player.openRedirectWindow(url);
4656 });
4657 }
4658 },
4659
4660 enableLogo: function() {
4661 this.logo.style.display = 'block';
4662 },
4663
4664 disableLogo: function() {
4665 this.logo.style.display = 'none';
4666 },
4667
4668 enableVolumeBtn: function() {
4669 this.volumeBtn.style.display = 'block';
4670 },
4671
4672 disableVolumeBtn: function() {
4673 this.volumeBtn.style.display = 'none';
4674 },
4675
4676 enableVolumeBar: function() {
4677 this.volumeSliderContainer.style.display = 'block';
4678 },
4679
4680 disableVolumeBar: function() {
4681 this.volumeSliderContainer.style.display = 'none';
4682 },
4683
4684 // proxy function to duplicate mouse touch event handlers
4685 addClickEvent: function(el, func) {
4686 var touchStartY, fingerMoved;
4687 el.addEventListener('touchstart', function(e) {
4688 touchStartY = e.touches[0].screenY;
4689 fingerMoved = false;
4690 });
4691 el.addEventListener('touchmove', function(e) {
4692 if (Math.abs(touchStartY - e.changedTouches[0].screenY) > 10) {
4693 fingerMoved = true;
4694 }
4695 });
4696 el.addEventListener('touchend', function(e) {
4697 if (!fingerMoved) {
4698 func.call(this, e);
4699 }
4700 });
4701
4702 el.addEventListener('mouseup', function(e) {
4703 // filter out right mouse button
4704 if (e.button === 0 && !isTablet) {
4705 func.call(this,e);
4706 }
4707 });
4708 },
4709
4710 //TOP BAR
4711 initTopBar: function() {
4712 var self = this,
4713 player = this.player,
4714 topBar = this.elements.topBar,
4715 embeds = this.settings.embeds,
4716 logoUrl = embeds.redirect.logoUrl;
4717
4718 this.topBar = xest(topBar.container);
4719 this.topBarTitle = xest(topBar.title);
4720
4721 if (player.mainRoll.title) {
4722 this.topBarTitle.innerHTML = player.mainRoll.title;
4723
4724 if (isPath(logoUrl)) {
4725 addClass(this.topBarTitle, 'isLink');
4726
4727 this.addClickEvent(this.topBarTitle, function() {
4728 var url = player.addCurrentTimeToUrl(logoUrl);
4729 if (embeds.utmRedirect.logo) {
4730 url = player.addUTM(url, 'embed', 'embed-title-html5');
4731 }
4732
4733 player.pause();
4734 player.openRedirectWindow(url);
4735 });
4736 }
4737 }
4738 },
4739
4740 initShareBtn: function() {
4741 var self = this,
4742 player = this.player,
4743 elements = this.elements,
4744 embeds = this.settings.embeds,
4745 logoUrl = embeds.redirect.logoUrl;
4746
4747 this.shareBtn = xest(elements.share);
4748
4749 this.addClickEvent(this.shareBtn, function() {
4750 if (embeds.enabled && isPath(logoUrl)) {
4751 var url = player.addCurrentTimeToUrl(logoUrl);
4752 url = player.addUTM(url, 'embed', 'embed-share-html5');
4753 player.pause();
4754 player.openRedirectWindow(url);
4755 } else {
4756 player.fireShareEvent();
4757 }
4758 });
4759 },
4760
4761 // quality MENU
4762 createQualityMenu: function() {
4763 var self = this,
4764 player = this.player,
4765 options = this.elements.controls.options,
4766 settings = this.settings;
4767
4768 this.optionsContainer = xest(options.container);
4769 this.optionsBtn = xest(options.button);
4770 this.optionsMenu = xest(options.menu.container);
4771 this.optionsMenuList = xest(options.menu.list);
4772
4773 if (parseInt(player.selectedResolution) >= settings.minHDQuality) {
4774 addClass(this.optionsBtn, 'isHD');
4775 }
4776
4777 this.optionsContainer.addEventListener('mousemove', function(e) {
4778 self.clearHideControlsTimer();
4779 clearTimeout(self.optionsMenuTimer);
4780 e.stopPropagation();
4781 });
4782
4783 this.optionsContainer.addEventListener('mouseout', function(e) {
4784 self.optionsMenuTimer = setTimeout(function() {
4785 self.hideOptions();
4786 self.enableTooltip(self.optionsBtn);
4787 }, 200);
4788 });
4789
4790 this.addClickEvent(this.optionsBtn, function() {
4791 if (self.player.adsRoll()) return false;
4792
4793 if (!self.optionsVisible) {
4794 self.showOptions();
4795 // special case, have to hide it on menu open
4796 self.hideTooltip();
4797 self.disableTooltip(this);
4798 } else {
4799 self.hideOptions();
4800 self.enableTooltip(this);
4801 }
4802 });
4803
4804 each(player.videoResolutions, function(resolution) {
4805 var newItem = s('li'),
4806 resolutionName = String(resolution).replace('_', 'p');
4807
4808 if (resolutionName.indexOf('p') == -1) {
4809 resolutionName += 'p';
4810 }
4811
4812 if (parseInt(resolution) >= settings.minUHDQuality) {
4813 resolutionName += ' <b>4K</b>';
4814 } else if (parseInt(resolution) >= settings.minHDQuality) {
4815 resolutionName += ' <b>HD</b>';
4816 }
4817
4818 if (resolution == 'hls' || resolution == 'dash') {
4819 resolutionName = l('%AUTO_QUALITY%');
4820 addClass(newItem, 'adaptive');
4821 }
4822
4823 newItem.innerHTML = resolutionName;
4824 newItem.rel = resolution;
4825
4826 if (resolution == player.selectedResolution) {
4827 addClass(newItem, 'active');
4828 }
4829
4830 if (player.videoSources[resolution].format == 'upsell') {
4831 addClass(newItem, 'upsell');
4832 newItem.innerHTML += '<span class="mhp1138_icon mhp1138_icon-star"></span>';
4833 }
4834
4835 self.optionsMenuList.appendChild(newItem);
4836 });
4837
4838 this.optionsMenuListItems = zest(options.menu.items);
4839
4840 each(this.optionsMenuListItems, function(item) {
4841 self.addClickEvent(item, function() {
4842 var resolution = item.rel,
4843 prevResolution = '',
4844 adaptiveItem = xest(options.menu.adaptive);
4845
4846 //already selected
4847 if (resolution == player.selectedResolution) {
4848 return;
4849 }
4850
4851 if (player.videoSources[resolution].format == 'upsell') {
4852 //is upsell
4853 player.fireUpsellEvent();
4854 } else {
4855 //change quality
4856 player.setQuality(resolution, function() {
4857 each(self.optionsMenuListItems, function(item2) {
4858 if (__.hasClass(item2, 'active')) {
4859 prevResolution = item2.rel;
4860 }
4861 removeClass(item2, 'active');
4862 });
4863
4864 addClass(item, 'active');
4865 if (parseInt(resolution) >= settings.minHDQuality) {
4866 addClass(self.optionsBtn, 'isHD');
4867 } else {
4868 removeClass(self.optionsBtn, 'isHD');
4869 }
4870
4871 (__.debounce(function() {
4872 self.hideOptions();
4873 }, 200))();
4874 });
4875
4876 if ((player.selectedFormat == 'dash' || player.selectedFormat == 'hls') && adaptiveItem) {
4877 if (player.selectedFormat == resolution) {
4878 adaptiveItem.innerHTML = l('%AUTO_QUALITY%') + ' <span>(' + prevResolution + ')</span>';
4879 } else {
4880 adaptiveItem.innerHTML = l('%AUTO_QUALITY%');
4881 }
4882 }
4883 }
4884 });
4885 });
4886 },
4887
4888 // create and init slow motion button
4889 createSlowMotionBtn: function() {
4890 var self = this,
4891 player = this.player,
4892 options = this.elements.controls.options,
4893 switchers = xest(options.switchers);
4894
4895 this.optionsSlowMotion = s('.optionSwitch.slowMotion');
4896
4897 this.optionsSlowMotion.innerHTML = l('%SLOWMOTION%') + ' <span><div></div></span>';
4898 switchers.appendChild(this.optionsSlowMotion);
4899
4900 this.addClickEvent(this.optionsSlowMotion, function(e) {
4901 if (player.slowMotion === 1) {
4902 player.setMotionRate(0.5);
4903 } else {
4904 player.setMotionRate(1);
4905 }
4906
4907 // prevent mouse event if initiated by touch
4908 e.preventDefault();
4909 });
4910 },
4911
4912 // create and init autoplay button
4913 createAutoplayBtn: function() {
4914 var self = this,
4915 player = this.player,
4916 options = this.elements.controls.options,
4917 switchers = xest(options.switchers);
4918
4919 this.optionsAutoplay = s('.optionSwitch.autoplay');
4920
4921 this.optionsAutoplay.innerHTML = l('%AUTOPLAY% <span><div></div></span>');
4922 switchers.appendChild(this.optionsAutoplay);
4923 self.setAutoplayState(player.autoplay);
4924
4925 this.addClickEvent(this.optionsAutoplay, function(e) {
4926 if (player.autoplay) {
4927 player.saveAutoplay(false);
4928 } else {
4929 player.saveAutoplay(true);
4930 }
4931
4932 // prevent mouse event if initiated by touch
4933 e.preventDefault();
4934 });
4935 },
4936
4937// -------------------- Hotspots --------------------
4938
4939 // create and init hotspots button
4940 createHotspotsBtn: function() {
4941 var self = this,
4942 player = this.player,
4943 options = this.elements.controls.options,
4944 switchers = xest(options.switchers);
4945 popup = xest(options.optionsPopup);
4946
4947 this.optionsHotspots = s('.optionSwitch.hotspots');
4948 this.optionsHotspots.innerHTML = l('%HOTSPOTS%') + '<span><div></div></span>';
4949
4950 var infoBtn = s('div.icon.icon-info');
4951
4952 this.setTooltipText(infoBtn, l('%HOTSPOTS_HOT_NOT%'));
4953 this.bindTooltipEvents(infoBtn);
4954
4955 this.optionsHotspots.insertBefore(infoBtn, this.optionsHotspots.childNodes[0]);
4956 switchers.appendChild(this.optionsHotspots);
4957
4958 this.addClickEvent(this.optionsHotspots, function(e) {
4959 if (player.hotspotsState) {
4960 player.setHotspotsState(false);
4961 } else {
4962 player.setHotspotsState(true);
4963 }
4964 self.toggleHotspotsGraphVisibility();
4965
4966 // prevent mouse event if initiated by touch
4967 e.preventDefault();
4968 });
4969 this.setHotspotsState();
4970 },
4971
4972 createHotspotsGraph: function(){
4973 var player = this.player,
4974 hotspotsTemplate = xest(
4975 '#mhp1138_skin .mhp1138_svg_hotspots'
4976 ),
4977 hotspotsSettings = this.settings.hotspots,
4978 embeds = this.settings.embeds,
4979 polygon = null,
4980 points = '',
4981 cntWidth = 1000, //viewBox area width
4982 cntHeight = 100; //viewBox area height
4983
4984 if (hotspotsSettings.data.length) {
4985 hotspotsSettings.data.splice(0, 2);
4986 }
4987
4988 var l = hotspotsSettings.data.length, //amount of points on graph
4989 intervalWidth = cntWidth/(l-1), // counting interval width
4990 intervalHeightDef = Math.max.apply(null, hotspotsSettings.data)/cntHeight; // counting 1% of maximum point
4991
4992 if (!__.isUndefined(hotspotsTemplate) && !embeds.enabled) {
4993 var templateClone = (hotspotsTemplate.firstChild || hotspotsTemplate.content.firstChild).cloneNode(true);
4994 templateClone.getElementsByTagName('clipPath')[0].setAttribute('id', this.container.getAttribute('id')+'_hotspotsClip');
4995 templateClone.getElementsByTagName('g')[0].setAttribute('clip-path', 'url(#'+this.container.getAttribute('id')+'_hotspotsClip)');
4996 this.seekBarElement.appendChild(templateClone);
4997
4998 var hotspots = this.elements.hotspots;
4999 polygon = xest(hotspots.polygon);
5000 this.hotspotsContainer = xest(hotspots.container);
5001 this.hotspotsProgress = xest(hotspots.progress);
5002 this.hotspotsProgress.setAttribute('fill', hotspotsSettings.chartColor);
5003
5004 this.hotspotsContainer.style.height = hotspotsSettings.chartHeight;
5005
5006 // Building points for polygon
5007 for(var i=0; i < l; i++){
5008 var item = parseInt(hotspotsSettings.data[i]),
5009 height = Math.floor(item/intervalHeightDef);
5010 points += (intervalWidth*i) + ',' + (cntHeight-height) + ' ';
5011 }
5012
5013 if (MHP1138.detector.isIe() || MHP1138.detector.isEdge()){
5014 this.seekBarProgressElement.style.transition = 'none';
5015 this.hotspotsProgress.setAttribute('transform', 'translate(-1000)');
5016 }
5017
5018 //Lines to finish the polygon
5019 points += intervalWidth*l + ',' + cntHeight + ' ' + '0,' + cntHeight;
5020
5021 polygon.setAttribute('points', points);
5022 this.toggleHotspotsGraphVisibility();
5023 }
5024 },
5025
5026 toggleHotspotsGraphVisibility: function(){
5027 var player = this.player;
5028 if (this.hotspotsContainer) {
5029 if (player.hotspotsState) {
5030 this.hotspotsContainer.style.display = 'block';
5031 } else {
5032 this.hotspotsContainer.style.display = 'none';
5033 }
5034 }
5035 },
5036
5037// -------------------- Hotspots --------------------
5038
5039 createGrid: function() {
5040 if (!__.isUndefined(MHP1138.gridMenu)) {
5041 this.grid = new MHP1138.gridMenu();
5042 this.grid.init(this.player);
5043 }
5044 },
5045
5046 initEventCatcher: function() {
5047 var self = this,
5048 player = this.player,
5049 embeds = this.settings.embeds,
5050 logoUrl = embeds.redirect.logoUrl;
5051
5052 //PLAY/PAUSE TOGGLE WHEN CLICKING ON THE VIDEO
5053 this.eventCatcher = xest(this.elements.eventCatcher);
5054
5055 // event catcher is hidden in VR mode
5056 if (this.settings.isVr && embeds.enabled) { return false; }
5057
5058 this.addClickEvent(this.eventCatcher, function(e) {
5059 // not a left mouse button clicked
5060 if (e.button && e.button != 0) { return false; }
5061 if (self.contextMenuShown) { return false; }
5062 // volume bar handle just released
5063 // and eventHandler gets an event before document (where volume handler is attached)
5064 if (self.volumeBarMouseDown) { return false; }
5065
5066 if (e.type == 'touchend') {
5067 // do not fire emulated mouseup event if processing touchend
5068 e.preventDefault();
5069 e.stopPropagation();
5070 }
5071
5072 if (embeds.enabled && embeds.utmRedirect.videoArea) {
5073 var url = player.addUTM(player.addCurrentTimeToUrl(logoUrl), 'embed', 'embed-html5');
5074 player.pause();
5075 player.openRedirectWindow(url);
5076 return false;
5077 }
5078
5079 var roll = player.adsRoll();
5080 if (roll && isPath(roll.clickUrl) &&
5081 player.videoStarted
5082 ) {
5083 player.adsRollTracking(roll, 'click');
5084 player.openRedirectWindow(roll.clickUrl);
5085 return false;
5086 }
5087
5088 // fullscreen button enabled in UI
5089 // separate single and double clicks
5090 if (self.settings.features.fullscreen) {
5091 // timer is still there, user made a second click (or tap) in doubleClickInterval!
5092 if (self.singleClickTimer) {
5093 self.processDoubleClick(e);
5094 clearTimeout(self.singleClickTimer);
5095 self.singleClickTimer = false;
5096 return false;
5097 }
5098
5099 // get timer descriptor
5100 self.singleClickTimer = setTimeout(function() {
5101 self.processSingleClick(e);
5102 self.singleClickTimer = false;
5103 }, self.doubleClickInterval);
5104
5105 // just do single click code instantly
5106 } else {
5107 self.processSingleClick(e);
5108 }
5109 });
5110 },
5111
5112 // 'click' means both events here (mouseup/touchend)
5113 processSingleClick: function(e) {
5114 // tablets do not play/pause on taps
5115 // but toggle interface visibility
5116 if (e.type == 'touchend') {
5117 this.processSingleTap(e);
5118 return false;
5119 }
5120
5121 if (this.playerReady) {
5122 this.player.togglePlayPause();
5123 }
5124 },
5125
5126 processDoubleClick: function(e) {
5127 var player = this.player;
5128 if (isTablet && !player.videoStarted) {
5129 player.play();
5130 }
5131 player.fullscreen.toggle();
5132 },
5133
5134 // tablets only code
5135 processSingleTap: function(e) {
5136 if (this.optionsVisible) {
5137 this.hideOptions();
5138 } else {
5139 if (this.hiddenControls) {
5140 this.showControls(true);
5141 this.showSeekBarHandle();
5142 if (this.volumeSlider) {
5143 this.volumeSlider.show();
5144 }
5145 } else {
5146 this.hideControls();
5147 this.hideSeekBarHandle();
5148 if (this.volumeSlider) {
5149 // small delay added to play animation _after_ controlsBar
5150 this.volumeSlider.autoHide(200);
5151 }
5152 }
5153 }
5154 e.preventDefault();
5155 },
5156
5157 createOverlays: function() {
5158 var self = this,
5159 overlays = this.player.overlays,
5160
5161 cssDimensions = ['top', 'left', 'right', 'bottom', 'width', 'height', 'margin', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft'],
5162 cssProperties = cssDimensions.concat(['font', 'fontSize', 'fontFamily', 'fontWeight', 'lineHeight', 'textAlign', 'color', 'background', 'backgroundImage']),
5163
5164 defaults = {
5165 time: 0,
5166 duration: 0,
5167 label: '',
5168 iframeUrl: '',
5169 imageUrl: '',
5170 clickUrl: '',
5171 clickTrackUrl: [],
5172 closeButton: true,
5173 border: true,
5174 hCentered: false,
5175 fontScale: false,
5176 // TODO: not supported yet
5177 //vCentered: false,
5178 //container: 'player'
5179 },
5180 options, element, closeBtn;
5181
5182
5183 this.overlayElements = [];
5184 this.overlays = [];
5185
5186 each(overlays, function(item) {
5187 // cloning overlays from mainRoll settings to internal skin arr + applyin defaults
5188 options = __.clone(defaults);
5189 __.extend(options, item)
5190 self.overlays.push(options);
5191
5192 element = s('.overlayText.hidden');
5193 for (var key in options) {
5194 if (cssProperties.indexOf(key) != -1) {
5195 element.style[key] = options[key];
5196 }
5197 }
5198
5199 wrapper = s('.text');
5200 if (isPath(options.imageUrl)) {
5201 wrapper.innerHTML = '<img src="' + options.imageUrl + '">';
5202 addClass(element, 'banner');
5203 } else if (isPath(options.iframeUrl)) {
5204 wrapper.innerHTML = '<iframe src="'+ options.iframeUrl + '" width="' + options.width + '" height="' + options.height + '"></iframe>';
5205 } else {
5206 wrapper.innerHTML = options.label;
5207 }
5208
5209 element.appendChild(wrapper);
5210
5211 if (isPath(options.clickUrl)) {
5212 addClass(element, 'link');
5213 self.addClickEvent(wrapper, function(e) {
5214 if (self.seekBarMouseDown || self.volumeBarMouseDown) return false;
5215 self.player.pause();
5216 self.player.openRedirectWindow(options.clickUrl);
5217
5218 if (options.clickTrackUrl.length) {
5219 each(options.clickTrackUrl, function(link) {
5220 __.ajaxLoader(link);
5221 });
5222 }
5223
5224 e.stopPropagation();
5225 e.preventDefault();
5226 });
5227 }
5228
5229 if (options.hCentered) { addClass(element, 'hCentered'); }
5230 if (options.vCentered) { addClass(element, 'vCentered'); }
5231 if (!options.border) { addClass(element, 'noBorder'); }
5232 self.calcOverlayFontScale(element, options);
5233
5234 if (options.closeButton) {
5235 closeBtn = s('.closeButton[html=×]');
5236 self.addClickEvent(closeBtn, function(e) {
5237 addClass(this.parentNode.parentNode, 'closed');
5238
5239
5240 // TODO: need to delete it from overlay arrays also
5241 e.stopPropagation();
5242 e.preventDefault();
5243 });
5244 wrapper.appendChild(closeBtn);
5245 }
5246
5247 self.eventCatcher.appendChild(element);
5248 self.overlayElements.push(element);
5249 });
5250 },
5251
5252 calcOverlayFontScale: function(element, options) {
5253 if (options.fontScale && options.fontScale.indexOf("%") != -1) {
5254 element.style.fontSize = Math.round(this.container.clientWidth / 100 * parseFloat(options.fontScale))+"px";
5255 }
5256 },
5257
5258 startOverlayTimers: function() {
5259 this.stopOverlayTimers();
5260
5261 var self = this,
5262 currentTime = this.player.playerElement.currentTime,
5263 endTime;
5264
5265 each(this.overlays, function(overlay, index) {
5266 endTime = overlay.time + overlay.duration;
5267
5268 if (overlay.time > currentTime) {
5269 overlay.showTimer = setTimeout(function() {
5270 self.showOverlay(self.overlayElements[index]);
5271 }, (overlay.time - currentTime) * 1000);
5272 }
5273
5274 if (endTime > currentTime) {
5275 overlay.hideTimer = setTimeout(function() {
5276 self.hideOverlay(self.overlayElements[index]);
5277 }, (endTime - currentTime) * 1000);
5278 }
5279 })
5280 },
5281
5282 stopOverlayTimers: function() {
5283 each(this.overlays, function(overlay, index) {
5284 clearTimeout(overlay.showTimer);
5285 clearTimeout(overlay.hideTimer);
5286 });
5287 },
5288
5289 showOverlay: function(overlayElement) {
5290 removeClass(overlayElement, 'hidden');
5291 },
5292
5293 hideOverlay: function(overlayElement) {
5294 addClass(overlayElement, 'hidden');
5295 },
5296
5297 hideOverlays: function() {
5298 var self = this;
5299 each(this.overlayElements, function(element) {
5300 self.hideOverlay(element);
5301 });
5302 },
5303
5304 setOverlaysVisibility: function(currentTime) {
5305 var self = this,
5306 endTime,
5307 element;
5308 if (!currentTime) {
5309 currentTime = this.player.playerElement.currentTime;
5310 }
5311
5312 each(this.overlays, function(overlay, index) {
5313 endTime = overlay.time + overlay.duration;
5314 element = self.overlayElements[index];
5315
5316 if (overlay.time <= currentTime && endTime > currentTime) {
5317 self.showOverlay(element);
5318 } else {
5319 self.hideOverlay(element);
5320 }
5321 });
5322 },
5323
5324 recalcOverlayFonts: function() {
5325 var self = this,
5326 element;
5327
5328 each(this.overlays, function(overlay, index) {
5329 element = self.overlayElements[index];
5330 self.calcOverlayFontScale(element, overlay);
5331 });
5332 },
5333
5334 deleteOverlays: function() {
5335 each(this.overlayElements, function(el) {
5336 el.parentNode.removeChild(el);
5337 });
5338 this.overlayElements = [];
5339 },
5340
5341 initTimeLabels: function() {
5342 var self = this,
5343 time = this.elements.controls.time;
5344
5345 this.currentTime = xest(time.elapsed);
5346 this.durationTime = xest(time.total)
5347 var time = xest(time.container);
5348 time.style.minWidth = time.clientWidth + 'px';
5349 // fix container jumping width for '11:11' time stamps
5350 },
5351
5352 initButtonHoversOnTouch: function() {
5353 var buttons = zest('#' + this.player.playerId + ' .mhp1138_btn');
5354 each(buttons, function(btn) {
5355 btn.addEventListener('touchstart', function(e) {
5356 addClass(btn, 'hover');
5357 e.preventDefault();
5358 });
5359
5360 btn.addEventListener('touchend', function() {
5361 removeClass(btn, 'hover');
5362 });
5363 });
5364 },
5365
5366 initPlaybackControls: function() {
5367 var self = this,
5368 player = this.player,
5369 controls = this.elements.controls,
5370 eventCatcher = this.eventCatcher;
5371
5372 this.playBtn = xest(controls.play);
5373 this.replayBtn = xest(controls.replay);
5374 this.pauseBtn = xest(controls.pause);
5375 this.bigPlayBtn = xest(controls.bigPlay);
5376 this.pausedByUser = false;
5377
5378 // tablet hackery
5379 // the very first of videotag's play() calls should be initiated by 'fully bubbled' event,
5380 // which is 'click', and not touchend/mouseup
5381 this.bigPlayBtn.addEventListener('click', function() { if (!self.settings.isVr) { eventCatcher.style.display = 'block'; } player.play(); });
5382 // hiding eventCatcher on touchstart to allow bubbling and generation of emulated 'click' event
5383 this.bigPlayBtn.addEventListener('touchstart', function() {
5384 eventCatcher.style.display = 'none';
5385 });
5386 this.bigPlayBtn.addEventListener('touchend', function(e) {
5387 e.stopPropagation();
5388 e.preventDefault();
5389
5390 eventCatcher.style.display = 'block';
5391 // ios 10 / 11 do not generate 'click' for the first time
5392 // but allow us to start playback with touchevents
5393 player.play();
5394 });
5395 this.bigPlayBtn.addEventListener('touchcancel', function() {
5396 eventCatcher.style.display = 'block';
5397 });
5398
5399 this.addClickEvent(this.playBtn, function() { player.play(); });
5400 this.addClickEvent(this.replayBtn, function() { player.play(); });
5401 this.addClickEvent(this.pauseBtn, function() {
5402 player.pause();
5403 self.pausedByUser = true;
5404 });
5405 },
5406
5407 initNextVideoBtn: function() {
5408 var player = this.player,
5409 nextVideo = this.settings.nextVideo;
5410
5411 // initial set of properties to show the button
5412 if (nextVideo.thumb &&
5413 isPath(nextVideo.nextUrl) &&
5414 nextVideo.title &&
5415 !this.settings.embeds.enabled
5416 ) {
5417 var nextBtn = s('.nextVideo'),
5418 nextIcon = s('.btn.icon.icon-next'),
5419 controls = this.elements.controls;
5420
5421 nextBtn.appendChild(nextIcon);
5422 // insert it before the timer (next to play/pause)
5423 xest(controls.container).insertBefore(nextBtn, xest(controls.time.container));
5424
5425 this.addClickEvent(nextBtn, function(e) {
5426 player.openRedirectWindow(nextVideo.nextUrl, true);
5427 e.preventDefault();
5428 e.stopPropagation();
5429 });
5430
5431 this.initNextVideoTips(nextVideo, nextBtn);
5432 }
5433 },
5434
5435 initNextVideoTips: function(nextVideo, nextBtn) {
5436 // elements required to create tip
5437 var controlsDiv = xest(this.elements.controls.container),
5438 tooltip = s('.nextVideoTooltip.hidden'),
5439 innerHTML = '',
5440 markup = {
5441 thumb: {
5442 _attributes: '[style="background-image:url(\"' + nextVideo.thumb + '\")"]',
5443 duration: (nextVideo.isHD?'span.hd[html=HD] + ':'') + 'span[html="%VIDEOTIME%"]'
5444 },
5445 text: '.next[html=' + l('%NEXT%').toUpperCase() +'] + .title[html=%TITLE%]'
5446 };
5447
5448 innerHTML = __.toMarkup(markup, 'mhp1138_');
5449 tooltip.innerHTML = innerHTML.replace('%TITLE%', nextVideo.title);
5450 tooltip.innerHTML = tooltip.innerHTML.replace('%VIDEOTIME%', __.secondToTime(nextVideo.duration));
5451 controlsDiv.appendChild(tooltip);
5452
5453 nextBtn.addEventListener('mouseenter', function() {
5454 removeClass(tooltip, 'hidden');
5455 });
5456
5457 nextBtn.addEventListener('mouseleave', function() {
5458 addClass(tooltip, 'hidden');
5459 });
5460 },
5461
5462 initVolumeBar: function() {
5463 var self = this,
5464 player = this.player,
5465 volumeControls = this.elements.controls.volume,
5466 slider = volumeControls.sliderPlugin;
5467
5468 // VOLUME BUTTON TOOLTIPS
5469 this.volumeBtn = xest(volumeControls.button);
5470 this.volumeLow = xest(volumeControls.low);
5471 this.volumeFull = xest(volumeControls.full);
5472 this.volumeMute = xest(volumeControls.mute);
5473
5474 this.addClickEvent(this.volumeLow, function() { player.setMute(true); });
5475 this.addClickEvent(this.volumeFull, function() { player.setMute(true); });
5476 this.addClickEvent(this.volumeMute, function() { player.setMute(false); });
5477
5478 this.volumeSliderContainer = xest(slider.container);
5479
5480 if (MHP1138.VolumeSlider && this.volumeSliderContainer) {
5481 this.volumeSlider = new MHP1138.VolumeSlider({
5482 playerContainer : document,
5483 sliderContainer : this.volumeSliderContainer,
5484 volumeBtn : this.volumeBtn, // container of 3 volume buttons
5485 zone : xest(slider.zone),
5486 mask : xest(slider.mask),
5487 horizontal : true,
5488 covers : zest(slider.covers),
5489 startingPosition: player.volume,
5490 onStartDrag : function() {
5491 self.volumeBarMouseDown = true;
5492 // manually clearing the timer for touch devices,
5493 // since they do not do this on playerContainer mousemove
5494 self.clearHideControlsTimer();
5495 },
5496 onEndDrag : function() {
5497 self.volumeBarMouseDown = false;
5498 // restarting the timer for touch devices
5499 self.startHideControlsTimer();
5500 },
5501 onChange : function(percentage) {
5502 player.setVolume(percentage);
5503 }
5504 }, s);
5505 }
5506 },
5507
5508 initFullscreenBtn: function() {
5509 var self = this,
5510 player = this.player,
5511 fullscreenControls = this.elements.controls.fullscreen,
5512 embeds = this.settings.embeds,
5513 redirect = embeds.redirect,
5514 logoUrl = redirect.logoUrl,
5515 quickSetup = this.settings.quickSetup,
5516 matchedDomain = quickSetup.match(/pornhub/i);
5517
5518 this.fullscreenBtn = xest(fullscreenControls.button);
5519 this.fullscreenOn = xest(fullscreenControls.on);
5520 this.fullscreenOff = xest(fullscreenControls.off);
5521
5522 this.addClickEvent(this.fullscreenBtn, function() {
5523 if (embeds.enabled &&
5524 isPath(logoUrl) &&
5525 redirect.onFullscreen &&
5526 matchedDomain === null
5527 ) {
5528 var url = player.addUTM(player.addCurrentTimeToUrl(logoUrl), 'embed', 'embed-fullscreen-html5');
5529 player.pause();
5530 player.openRedirectWindow(url);
5531 } else {
5532 if (isTablet && !player.videoStarted) {
5533 player.play();
5534 }
5535 player.fullscreen.toggle();
5536 self.hideTooltip();
5537 }
5538 });
5539
5540 this.toggleFullscreenVisibility();
5541 },
5542
5543 toggleFullscreenVisibility: function() {
5544 if(this.player.preRoll.enabled && isTablet && isIos) {
5545 this.iosFullscreenEnabled = false;
5546 addClass(this.container, 'fullscreenHidden');
5547 } else {
5548 this.iosFullscreenEnabled = true;
5549 removeClass(this.container, 'fullscreenHidden');
5550 }
5551 },
5552
5553 initChromecastBtn: function() {
5554 var self = this,
5555 player = this.player,
5556 chromecastControls = this.elements.controls.chromecast,
5557 settings = this.settings,
5558 isEdge = MHP1138.detector.isEdge(),
5559 isCastPlayable = !window.chrome || isEdge || !settings.features.chromecast || settings.isVr;
5560
5561 this.chromecastBtn = xest(chromecastControls.castBtn);
5562 //microsoft edge also implements window.chrome hence without edge detection condition becomes true and adds cast button
5563 if(isCastPlayable) {
5564 this.chromecastBtn.style.display = 'none';
5565 return false;
5566 }
5567
5568 this.addClickEvent(this.chromecastBtn, function(event) {
5569 player.pause();
5570 event.stopPropagation();
5571 });
5572 },
5573
5574 initCinemaModeBtn: function() {
5575 var self = this,
5576 player = this.player,
5577 cinemaControls = this.elements.controls.cinema;
5578
5579 this.cinemaModeBtn = xest(cinemaControls.button);
5580 this.cinemaModeNormal = xest(cinemaControls.normal);
5581 this.cinemaModeLarge = xest(cinemaControls.large);
5582
5583 this.addClickEvent(this.cinemaModeBtn, function() {
5584 player.toggleCinemaMode();
5585 // hacks to prevent displaying tooltip in the middle of resized player
5586 self.delayTooltip(self.cinemaModeLarge, 200);
5587 self.delayTooltip(self.cinemaModeNormal, 200);
5588 self.hideTooltip();
5589 });
5590 },
5591
5592 subscribeToPlayerEvents: function() {
5593 var self = this,
5594 player = this.player,
5595 controls = this.elements.controls,
5596 settings = this.settings;
5597
5598 // onReady event signals video tag existance and availability,
5599 // NOT actual video source readiness, see onVideoReady for that
5600 subscribeToEvent('onReady', function() {
5601 self.playerReady = true;
5602
5603 if (isTablet && settings.embeds.enabled) {
5604 self.showSeekBarHandle();
5605 }
5606 });
5607
5608 subscribeToEvent('onPlay', function() {
5609 self.setPlayerState('playing');
5610 self.setOverlaysVisibility();
5611 self.startOverlayTimers();
5612 // hide seekbar handle in a second after keyboard initiated events
5613 self.autoHideSeekBarHandle();
5614 self.pausedByUser = false;
5615 if(!self.iosFullscreenEnabled) {
5616 self.toggleFullscreenVisibility();
5617 }
5618 });
5619
5620 subscribeToEvent('onPause', function() {
5621 self.setPlayerState('paused');
5622 self.stopOverlayTimers();
5623 self.player.playing = false;
5624
5625 if(!self.pausedByUser && isTablet && isIos && !settings.embeds.enabled) {
5626 fireEvent('showPauseRoll');
5627 }
5628 });
5629
5630 subscribeToEvent('onKeyboard', function(i,e,o) {
5631 self.showControls();
5632 // show volume bar only if player is in the ready state
5633 if (self.videoReadyForSeek && o.action.indexOf('volume') != -1) {
5634 self.volumeSlider.show();
5635 self.volumeSlider.autoHide(1000);
5636 }
5637 });
5638
5639 subscribeToEvent('onSeek', function(i,e,o) {
5640 self.setPlayerState('buffering');
5641 self.setOverlaysVisibility();
5642 });
5643
5644 subscribeToEvent('onDurationChange', function(i,e,o) {
5645 self.durationTime.innerHTML = __.secondToTime(o.duration);
5646 });
5647
5648 subscribeToEvent('onTimeChange', function(i,e,o) {
5649 self.currentTime.innerHTML = __.secondToTime(o.time);
5650
5651 if (self.seekBarMouseDown) return false;
5652 if (self.manualSeek) return false;
5653
5654 var duration = player.duration,
5655 currentTime = o.time;
5656
5657 self.seekPosition = (currentTime * 100 / duration);
5658 self.updateSeekBarPosition();
5659 });
5660
5661 subscribeToEvent('onWaiting', function() {
5662 self.setPlayerState('buffering');
5663 });
5664
5665 subscribeToEvent('onQualityChange', function() {
5666 self.setPlayerState('buffering');
5667 });
5668
5669 subscribeToEvent('onVideoReady', function() {
5670 if (!player.videoStarted) {
5671 self.setPlayerState('ready');
5672 }
5673 self.videoReadyForSeek = true;
5674
5675 if (player.hlsSource) {
5676 addClass(player.playerContainerElement, 'hlsStream');
5677 } else {
5678 removeClass(player.playerContainerElement, 'hlsStream');
5679 }
5680
5681 if (player.dashSource) {
5682 addClass(player.playerContainerElement, 'dashStream');
5683 } else {
5684 removeClass(player.playerContainerElement, 'dashStream');
5685 }
5686
5687 });
5688
5689 subscribeToEvent('onEnd', function() {
5690 self.setPlayerState('replay');
5691 self.showControls(); // WARN: do we need it on video end?
5692 self.stopOverlayTimers();
5693 });
5694
5695 subscribeToEvent('onFullscreen', function(i,e,o) {
5696 self.setFullscreenState(o.fullscreen);
5697 });
5698
5699 // do not react on chromecast generated events if the feature was disabled (by embed mode or manually from config)
5700 if (settings.features.chromecast) {
5701 subscribeToEvent('chromecastAvailable', function(i,e,o) {
5702 if (o.available) {
5703 addClass(player.playerContainerElement, 'chromecastV3');
5704 self.enableChromecastBtn();
5705 } else {
5706 self.disableChromecastBtn();
5707 }
5708 });
5709 }
5710
5711 subscribeToEvent('onCasting', function(i,e,o) {
5712 self.setChromecastState(o.chromecast);
5713 });
5714
5715 function rescaleOverlays() {
5716 self.hideOverlays()
5717 setTimeout(function() {
5718 self.recalcOverlayFonts();
5719 self.setOverlaysVisibility();
5720 }, 400);
5721 }
5722
5723 subscribeToEvent('collapsePlayer', function() {
5724 self.setCinemaState(false);
5725 rescaleOverlays();
5726 });
5727
5728 subscribeToEvent('expandPlayer', function() {
5729 self.setCinemaState(true);
5730 rescaleOverlays();
5731 });
5732
5733 subscribeToEvent('onVolumeChange', function(i,e,o) {
5734 if (o.muted) {
5735 self.setVolumeState('mute');
5736 } else {
5737 if (o.volume < 10) {
5738 self.setVolumeState('low');
5739 } else if (o.volume < 60) {
5740 self.setVolumeState('medium');
5741 } else {
5742 self.setVolumeState('full');
5743 }
5744 }
5745
5746 if (self.volumeSlider) {
5747 self.volumeSlider.setValue(o.volume);
5748 }
5749 });
5750
5751 subscribeToEvent('onAutoplayChange', function(i,e,o) {
5752 self.setAutoplayState(o.autoplay);
5753 });
5754
5755 subscribeToEvent('onSlowMotionChange', function(i,e,o) {
5756 self.setSlowMotionState(o.motionRate);
5757 });
5758
5759 subscribeToEvent('onHotspotsStateChange', function(i,e,o) {
5760 self.setHotspotsState(o.hotspotsState);
5761 self.toggleHotspotsGraphVisibility();
5762 });
5763
5764 subscribeToEvent('onAdaptiveQualityChange', function(i,e,o) {
5765 var menuOption = __.xest(self.elements.controls.options.menu.adaptive);
5766 if(!menuOption) return;
5767
5768 if((player.selectedResolution == 'hls' || player.selectedResolution == 'dash')){
5769 var quality = o.quality.height ? ' (' + o.quality.height + ')' : '';
5770 menuOption.innerHTML = l('%AUTO_QUALITY%') + quality;
5771 } else {
5772 menuOption.innerHTML = l('%AUTO_QUALITY%');
5773 }
5774 });
5775 },
5776
5777 videoNotAvailable: function(message) {
5778 var elements = this.elements,
5779 videoErrorMessage = elements.videoErrorMessage;
5780 //hide element that should have been hidden later if the video where available.
5781 xest(elements.bufferingWheel).style.display = 'none';
5782 xest(elements.controls.bar).style.display = 'none';
5783 xest(elements.controls.bigPlay).style.display = 'none';
5784 xest(elements.topBar.container).style.display = 'none';
5785 xest(elements.thumbnails.container).style.display = 'none';
5786
5787 if (!message) {
5788 message = this.player.mainRoll.videoUnavailableMessage;
5789 }
5790 if (!message) {
5791 message = l(this.settings.htmlSettings.notAvailableMessage)
5792 }
5793 xest(videoErrorMessage.container).style.display = 'block';
5794 xest(videoErrorMessage.text).innerHTML = message;
5795 },
5796
5797 setPlayerState: function(state) {
5798 var container = this.container,
5799 playerStates = ['ready', 'buffering', 'playing', 'paused', 'replay'];
5800
5801 if (playerStates.indexOf(state) != -1) {
5802 each(playerStates, function(state) {
5803 removeClass(container, state + 'State');
5804 })
5805 addClass(container, state + 'State');
5806 this.playerState = state;
5807 }
5808 },
5809
5810 setVolumeState: function(state) {
5811 var container = this.volumeBtn,
5812 volumeStates = ['low', 'medium', 'full', 'mute'];
5813
5814 if (volumeStates.indexOf(state) != -1) {
5815 each(volumeStates, function(state) {
5816 removeClass(container, state + 'Volume');
5817 })
5818 addClass(container, state + 'Volume');
5819 if (this.volumeSlider) {
5820 if (state == 'mute') {
5821 addClass(this.volumeSliderContainer, 'muted');
5822 } else {
5823 removeClass(this.volumeSliderContainer, 'muted');
5824 }
5825 }
5826 this.volumeState = state;
5827 }
5828 },
5829
5830 setFullscreenState: function(state) {
5831 this.setButtonState(state, this.fullscreenBtn, 'fullscreenState');
5832 },
5833
5834 setChromecastState: function(state) {
5835 this.setButtonState(state, this.chromecastBtn, 'chromecastState');
5836 },
5837
5838 setCinemaState: function(state) {
5839 this.setButtonState(state, this.cinemaModeBtn, 'cinemaState');
5840 },
5841
5842 setAutoplayState: function(state) {
5843 this.setButtonState(state, this.optionsAutoplay, 'stateOn');
5844 },
5845
5846 setSlowMotionState: function(state) {
5847 state = state == 1 ? false : true;
5848 this.setButtonState(state, this.optionsSlowMotion, 'stateOn');
5849 },
5850
5851 setHotspotsState: function(state) {
5852 if(this.settings.features.showHotspots && this.optionsHotspots){
5853 this.setButtonState(state, this.optionsHotspots, 'stateOn');
5854 }
5855 },
5856
5857 setButtonState: function(state, element, className) {
5858 if (state) {
5859 addClass(element, className);
5860 } else {
5861 removeClass(element, className);
5862 }
5863 },
5864
5865 initThumbnails: function() {
5866 var thumbnails = this.elements.thumbnails;
5867
5868 this.thumbnails = {
5869 container: xest(thumbnails.container),
5870 image: xest(thumbnails.image),
5871 sprite: xest(thumbnails.sprite),
5872 selectedTime: xest(thumbnails.selectedTime),
5873 arrow: xest(thumbnails.arrow),
5874 actionTagTitle: xest(thumbnails.actionTagTitle)
5875 };
5876
5877 this.hideThumbnailImage();
5878 this.hideThumbnail();
5879 },
5880
5881 hideThumbnail: function () {
5882 addClass(this.thumbnails.container, 'hidden');
5883 // remove hover zone when leaving thumbnails bar
5884 if (this.seekBarContainer) {
5885 removeClass(this.seekBarContainer, 'thumbnailsHoverZone');
5886 }
5887 },
5888
5889 showThumbnail: function() {
5890 removeClass(this.thumbnails.container, 'hidden');
5891 },
5892
5893 hideThumbnailImage: function() {
5894 addClass(this.thumbnails.container, 'noImage');
5895 if (this.seekBarContainer) {
5896 removeClass(this.seekBarContainer, 'thumbnailsHoverZone');
5897 }
5898 },
5899
5900 showThumbnailImage: function(thumbnail, sheet) {
5901 var thumbnails = this.thumbnails,
5902 reposition;
5903
5904 // new spritesheet was loaded and going to be shown for the first time
5905 if (thumbnails.image.src != sheet.url) {
5906 thumbnails.image.src = sheet.url;
5907 thumbnails.sprite.style.width = sheet.thumbWidth + 'px';
5908 thumbnails.sprite.style.height = sheet.thumbHeight + 'px';
5909 reposition = true;
5910 }
5911
5912 // The fix for wrong image size of thumbnails file happened on YP TFE-914
5913 thumbnails.image.style.left = (-1 * thumbnail.col * sheet.thumbWidth + 'px');
5914 thumbnails.image.style.top = (-1 * thumbnail.row * sheet.thumbHeight + 'px');
5915 removeClass(thumbnails.container, 'noImage');
5916
5917 // need this check here because show/hideThumbnail could be called before seekBar init
5918 // do not increase hover zone for embedded players
5919 if (this.seekBarContainer && !this.settings.embeds.enabled) {
5920 addClass(this.seekBarContainer, 'thumbnailsHoverZone');
5921 }
5922
5923 // deferred reposition of the thumbnail tooltip with updated width
5924 // because it was already shown for small 'time only' tooltip
5925 if (reposition) {
5926 this.trackThumbnailMousePosition(this.lastMouseEvent);
5927 }
5928 },
5929
5930 updateThumbnailTime: function(seconds) {
5931 this.thumbnails.selectedTime.innerHTML = __.secondToTime(seconds);
5932 },
5933
5934 updateThumbnailImage: function(seconds) {
5935 var self = this;
5936 var info = this.player.thumbnails.get(seconds, function(thumbnail, sheet, error) {
5937 if (thumbnail && sheet) {
5938 self.showThumbnailImage(thumbnail, sheet);
5939 }
5940 });
5941
5942 if (!info) {
5943 this.hideThumbnailImage();
5944 }
5945 },
5946
5947 updateThumbnailActionTag: function(position) {
5948 if (!this.actionTagCache || !this.actionTagCache.length) return false;
5949
5950 var i = 0,
5951 found = false,
5952 tag, endPos, seekBarWidth, tagWidth;
5953
5954 // seekbar wasnt measured yet
5955 if (!this.seekBarZoneOffset) {
5956 this.seekBarZoneOffset = this.seekBarElement.getBoundingClientRect();
5957 }
5958 seekBarWidth = this.seekBarZoneOffset.width;
5959
5960 while (!found && i < this.actionTagCache.length) {
5961 tag = this.actionTagCache[i];
5962 endPos = tag.endPos;
5963 tagWidth = this.percentToPixel(endPos, seekBarWidth) - this.percentToPixel(tag.startPos, seekBarWidth);
5964 // 1sec mark could become smaller than 1px in lengthy vids, so we limit
5965 // min-width: 4px for them (hardcoded in css)
5966 if (tagWidth < 4) {
5967 // enlarge your pixels!
5968 endPos = tag.startPos + this.pixelToPercent(4, seekBarWidth);
5969 }
5970 if (position >= tag.startPos && position <= endPos) { found = true; }
5971 i++;
5972 }
5973
5974 if (found) {
5975 this.highlightActionTagByName(tag.name);
5976 this.setThumbnailActionTag(tag.name);
5977 this.activeActionTag = tag.name; // caching tag name to clear highlight on mouseleave
5978 } else {
5979 this.clearActionTagHighlightByName(this.activeActionTag);
5980 this.setThumbnailActionTag(false);
5981 this.activeActionTag = false;
5982 }
5983 },
5984
5985 //SEEK BAR
5986 initSeekBar: function() {
5987 var self = this,
5988 player = this.player,
5989 settings = player.settings,
5990 seekBar = this.elements.controls.seekBar;
5991
5992 this.seekBarContainer = xest(seekBar.container);
5993 this.seekBarElement = xest(seekBar.bar);
5994 this.seekBarBufferElement = xest(seekBar.buffer);
5995 this.seekBarProgressElement = xest(seekBar.progress);
5996 this.seekBarHandleElement = xest(seekBar.handle);
5997 this.seekBarHandleWidth = this.seekBarHandleElement.getBoundingClientRect().width;
5998
5999 this.bufferedRanges = [];
6000 this.bufferedRangesInfo = [];
6001
6002 //this.playerWasPlaying-> used to set state of player(ply or pause) after seek is performed
6003 //initial value for tablet should be false as seeking before playback doesn't starts video.
6004 this.playerWasPlaying = isTablet ? false : true;
6005
6006 // playerElement COULD be empty if player.noValidVideoSource is set
6007 if (!this.player.playerElement) return;
6008
6009 this.seekBarAddAnimation();
6010
6011 function prepareDrag(e) {
6012 if (this.volumeBarMouseDown) return false; // volume bar is draging, no preview
6013 if (!player.duration) return false; // player is not ready
6014 if (player.adsRoll() && !player.isPauseRollActive) return false;
6015 if (player.deferredPreRoll) return false; // prevent seek
6016
6017 this.seekBarMouseOver = true;
6018 this.updateThumbnail();
6019 this.showSeekBarHandle();
6020 this.trackThumbnailMousePosition(e)
6021 }
6022
6023 this.seekBarElement.addEventListener('mouseenter', prepareDrag.bind(this));
6024 this.seekBarElement.addEventListener('touchstart', prepareDrag.bind(this));
6025
6026 function startDrag(e) {
6027 if (!this.seekBarMouseOver) return false;
6028 if (!this.videoReadyForSeek) return false;
6029
6030 if (e.button == 0 || e.touches && e.touches.length) {
6031 //stop text selection
6032 e.preventDefault();
6033
6034 this.seekBarMouseDown = true;
6035 this.seekBarMouseMoved = false;
6036
6037 if (!this.player.seeking && this.player.videoStarted) {
6038 this.playerWasPlaying = !player.playerElement.paused;
6039 this.player.playing = this.playerWasPlaying;
6040 this.pausedByUser = true;
6041 player.playerElement.pause();
6042 }
6043
6044 //we only calculate the bounding zone on the initial mousedown event to save cpu ressources
6045 //calculating it on every pixel during the mousemove event could use a lot of ressources for nothing.
6046 this.seekBarZoneOffset = this.seekBarElement.getBoundingClientRect();
6047
6048 this.seekBarRemoveAnimation();
6049 //we initiate the mousemove events so the can drag the slider around.
6050 this.trackSeekBarMousePosition(e);
6051
6052 addClass(this.container, 'seekBarDrag');
6053 }
6054 }
6055
6056 this.seekBarElement.addEventListener('mousedown', startDrag.bind(this));
6057 this.seekBarElement.addEventListener('touchstart', startDrag.bind(this));
6058
6059 this.seekBarElement.addEventListener('mouseleave', function() {
6060 if (self.seekBarMouseOver) {
6061 self.seekBarMouseOver = false;
6062
6063 if (!self.seekBarMouseDown) {
6064 self.updateThumbnail();
6065 self.hideSeekBarHandle();
6066 }
6067 self.clearActionTagHighlight();
6068 }
6069 });
6070
6071 this.seekBarElement.addEventListener('mousemove', function(e) {
6072 // show thumbnails while mouse hovers seekBar,
6073 // but dont do so, if handle tracking enabled (mousedowned)
6074 if (self.seekBarMouseOver && !self.seekBarMouseDown) {
6075 self.trackThumbnailMousePosition(e)
6076 }
6077 });
6078
6079 // mouseup/touchend
6080 this.addClickEvent(document, this.abortSeekBarMouseTracking.bind(this));
6081 document.addEventListener('touchend', function(e) {
6082 self.abortSeekBarMouseTracking(e);
6083 self.seekBarMouseOver = false;
6084 self.updateThumbnail();
6085 });
6086
6087 // drop the handle and do seek on exiting browser window
6088 document.addEventListener('mouseleave', function(e) {
6089 self.abortSeekBarMouseTracking(e);
6090 });
6091
6092 function trackDrag(e) {
6093 if (this.seekBarMouseDown) {
6094 this.trackSeekBarMousePosition(e);
6095 this.trackThumbnailMousePosition(e)
6096
6097 if (!this.seekBarMouseMoved) {
6098 this.updateSeekBarState();
6099 this.seekBarMouseMoved = true;
6100 }
6101 }
6102 }
6103
6104 document.addEventListener('mousemove', trackDrag.bind(this));
6105 this.seekBarElement.addEventListener('touchmove', trackDrag.bind(this));
6106
6107 // deferred seek will be done right after the first 'play' click
6108 // reposition the progress mark and timer
6109 if (!player.preRoll.enabled &&
6110 settings.startOffset &&
6111 player.mainRoll.duration
6112 ) {
6113 this.setSeekBarPosition(settings.startOffset, player.mainRoll.duration);
6114 player.updateCurrentTime(settings.startOffset);
6115 }
6116
6117 },
6118
6119 updateSeekBarState: function() {
6120 if (this.seekBarMouseDown) {
6121 this.seekBarRemoveAnimation();
6122 } else {
6123 this.seekBarAddAnimation();
6124 this.mousePosition.position = -100;
6125 if (!this.seekBarMouseOver &&
6126 !this.controlsShownByTouch
6127 ) {
6128 this.hideSeekBarHandle();
6129 }
6130 }
6131 },
6132
6133 hideSeekBarHandle: function() {
6134 removeClass(this.seekBarElement, 'showHandle');
6135 },
6136
6137 autoHideSeekBarHandle: function() {
6138 var self = this;
6139 clearTimeout(this.hideHandleTimer);
6140 this.hideHandleTimer = setTimeout(function() {
6141 if (!self.seekBarMouseOver &&
6142 !self.controlsShownByTouch &&
6143 !isTablet
6144 ) {
6145 self.seekBarAddAnimation();
6146 self.hideSeekBarHandle();
6147 }
6148 }, 1000);
6149 },
6150
6151 showSeekBarHandle: function() {
6152 addClass(this.seekBarElement, 'showHandle');
6153 clearTimeout(this.hideHandleTimer);
6154 },
6155
6156 abortSeekBarMouseTracking: function(e) {
6157 if (this.seekBarMouseDown) {
6158 removeClass(this.container, 'seekBarDrag');
6159
6160 this.trackSeekBarMousePosition(e);
6161 this.updateThumbnail();
6162 this.seekBarMouseDown = false;
6163 this.updateSeekBarState();
6164 this.seekToNewPosition();
6165 }
6166 },
6167
6168 setSeekBarPosition: function(time, duration) {
6169 this.seekPosition = time * 100 / duration;
6170 this.updateSeekBarPosition();
6171 },
6172
6173 trackSeekBarMousePosition: function(e) {
6174 if (!this.playerReady) return false;
6175 if (this.manualSeek) return false;
6176
6177 var position = this.calculateSeekbarMousePositionFromEvent(e, this.seekBarZoneOffset),
6178 previousSeekPosition = this.seekPosition,
6179 duration = this.player.duration,
6180 seconds = '';
6181
6182 this.seekPosition = this.pixelToPercent(position.position, position.range);
6183 this.mousePosition = position;
6184 if (!__.isNaN(duration)) {
6185 seconds = this.seekPosition * duration / 100;
6186 }
6187
6188 if (this.seekPosition != previousSeekPosition) {
6189 this.updateSeekBarPosition();
6190 this.player.updateCurrentTime(seconds);
6191 }
6192 },
6193
6194 updateSeekBarPosition: function() {
6195 var value = this.seekPosition,
6196 browser = MHP1138.detector.getBrowser(),
6197 isSafari = browser.name === 'safari',
6198 translateX = (-100 + value) + '%',
6199 //translate3d causes issues in safari embed
6200 cssTranslate = isSafari ? 'translate('+ translateX +',0)' : 'translate3d('+ translateX +',0,0)';
6201
6202 this.seekBarProgressElement.style.MozTransform = cssTranslate;
6203 this.seekBarProgressElement.style.webkitTransform = cssTranslate;
6204 this.seekBarProgressElement.style.msTransform = cssTranslate;
6205 this.seekBarProgressElement.style.transform = cssTranslate;
6206 this.seekBarHandleElement.style.left = value + '%';
6207
6208 if (!__.isUndefined(this.hotspotsProgress)) {
6209 this.hotspotsProgress.style.MozTransform = cssTranslate;
6210 this.hotspotsProgress.style.webkitTransform = cssTranslate;
6211 this.hotspotsProgress.style.msTransform = cssTranslate;
6212 this.hotspotsProgress.style.transform = cssTranslate;
6213
6214 if (MHP1138.detector.isIe() || MHP1138.detector.isEdge()) {
6215 this.hotspotsProgress.style.transition = 'none';
6216 this.hotspotsProgress.setAttribute('transform', 'translate(' + (1000/100*value-1000) + ')');
6217 }
6218 }
6219 },
6220
6221 //seek to new position on mouseup
6222 seekToNewPosition: function() {
6223 var duration = this.player.duration,
6224 position = this.seekPosition * duration / 100;
6225 this.player.seek(position, this.playerWasPlaying);
6226 // reset if used in moveSeekBarHandle method
6227 this.manualSeek = false;
6228 },
6229
6230 // triggered by keyboard events from player core
6231 moveSeekBarHandle: function(step) {
6232 if (!this.manualSeek) {
6233 this.manualSeek = this.player.playerElement.currentTime;
6234 // keydown events happen every ~50ms, no need in animation
6235 this.seekBarRemoveAnimation();
6236 this.showSeekBarHandle();
6237 }
6238 this.manualSeek += this.player.duration / 100 * step;
6239 this.seekPosition = this.manualSeek / this.player.duration * 100;
6240 if (this.seekPosition < 0) {
6241 this.seekPosition = 0;
6242 }
6243 if (this.seekPosition > 100) {
6244 this.seekPosition = 100;
6245 }
6246 this.updateSeekBarPosition();
6247 },
6248
6249 seekBarAddAnimation: function() {
6250 addClass(this.seekBarElement, 'animated');
6251 },
6252
6253 seekBarRemoveAnimation: function() {
6254 removeClass(this.seekBarElement, 'animated');
6255 },
6256
6257 deleteActionTags: function() {
6258 var self = this,
6259 actionTags = zest(this.elements.actionTag);
6260 each(actionTags, function(tag) {
6261 self.seekBarBufferElement.removeChild(tag);
6262 })
6263 },
6264
6265 createActionTags: function() {
6266 if (this.player.adsRoll()) {
6267 return false;
6268 }
6269
6270 var self = this,
6271 player = this.player,
6272 actionTags = player.actionTags,
6273 duration = player.duration,
6274 pairs, tagParts, tagElement;
6275
6276 this.actionTagGroups = {};
6277 this.actionTagTimes = {};
6278 this.actionTagCache = [];
6279
6280 if (actionTags && actionTags.length) {
6281 pairs = actionTags.split(",");
6282
6283 each(pairs, function(pair) {
6284 tagParts = pair.split(":");
6285 if (tagParts.length > 1) {
6286
6287 // careful, time parts are strings here
6288 if (tagParts.length < 3) {
6289 tagParts[2] = parseFloat(tagParts[1]) + 1;
6290 }
6291
6292 var tag = {
6293 name: tagParts[0],
6294 startTime: parseFloat(tagParts[1]),
6295 endTime: parseFloat(tagParts[2]),
6296 startPos: tagParts[1] / duration * 100, // starting timeline position (percentage)
6297 endPos: tagParts[2] / duration * 100 // ending timeline position
6298 };
6299
6300 if (tag.endPos > 100) { tag.endPos = 100; }
6301 if (tag.startPos < 0) { tag.startPos = 0; }
6302 if (tag.startPos > 100) return; // do not display tags outside of the seekbar
6303 tag.width = tag.endPos - tag.startPos; // positions diff, width of the tag mark (percentage)
6304
6305 self.actionTagCache.push(tag);
6306
6307 tagElement = s('.actionTag[data-tag=' + tag.name + ']');
6308 tagElement.style.left = tag.startPos + '%';
6309 tagElement.style.width = tag.width + '%';
6310
6311 self.seekBarBufferElement.appendChild(tagElement);
6312
6313 // creating same tag groups
6314 if (__.isUndefined(self.actionTagGroups[tag.name])) {
6315 self.actionTagGroups[tag.name] = [tagElement];
6316 } else {
6317 self.actionTagGroups[tag.name].push(tagElement);
6318 }
6319 self.actionTagTimes[tag.startTime] = tagElement;
6320 }
6321 });
6322 }
6323 },
6324
6325 clearActionTagHighlight: function() {
6326 each(this.actionTagGroups, function(group) {
6327 each(group, function(el) {
6328 removeClass(el, 'hover');
6329 })
6330 });
6331 },
6332
6333 highlightActionTagByName: function(name) {
6334 each(this.actionTagGroups[name], function(element) {
6335 addClass(element, 'hover');
6336 });
6337 },
6338
6339 clearActionTagHighlightByName: function(name) {
6340 each(this.actionTagGroups[name], function(element) {
6341 removeClass(element, 'hover');
6342 });
6343 },
6344
6345 //THUMBNAILS PREVIEW
6346 updateThumbnail: function() {
6347 if (!this.playerReady) {
6348 return false;
6349 }
6350
6351 if (this.seekBarMouseOver && !this.hiddenControls) {
6352 this.showThumbnail();
6353 } else {
6354 this.hideThumbnail();
6355 this.mousePosition.position = -100;
6356 }
6357 },
6358
6359 setThumbnailActionTag: function(tag) {
6360 if (tag) {
6361 if (tag != this.activeActionTag) {
6362 this.thumbnails.actionTagTitle.innerHTML = tag;
6363 this.thumbnails.actionTagTitle.style.display = 'block';
6364 }
6365 } else {
6366 if (this.activeActionTag) {
6367 this.thumbnails.actionTagTitle.style.display = 'none';
6368 }
6369 }
6370 },
6371
6372 trackThumbnailMousePosition: function(e) {
6373 //get the current mouse position on the seekbar
6374 var position = this.calculateSeekbarMousePositionFromEvent(e, this.seekBarElement.getBoundingClientRect());
6375 if (!position) return;
6376
6377 //WE CALCULATE THE CURRENT TIME AND DISPLAY IT
6378 //the selected position on the seek bar as a percentage of the total video duration
6379 var percentage = this.pixelToPercent(position.position, position.range);
6380
6381 //the selected position on the seek bar as a number of seconds since the beginning of the video.
6382 var seconds = percentage * this.player.duration / 100;
6383
6384 // updateThumbnailTime also updates visibility of thumbnail image
6385 // this call should be there, as we need to use updated
6386 // thumbnail container dimensions in the code below
6387 this.updateThumbnailTime(seconds);
6388 this.updateThumbnailImage(seconds);
6389 this.updateThumbnailActionTag(percentage);
6390
6391 //ajust that position to take the seekbar padding in concideration
6392 //they correspond to half of the seekbar handle on the left and right
6393 var rawPosition = position.position + (this.seekBarHandleWidth / 2);
6394
6395 //same position but ajusted to center the thumbnails preview windows in the middle over the selected section of the seekbar.
6396 var centeredPosition = rawPosition - (this.thumbnails.container.offsetWidth / 2);
6397
6398 //now we calculate the position the arrow need to be centered on the thumbnail preview box
6399 var arrowCenteredPosition = (this.thumbnails.container.offsetWidth / 2) - (this.thumbnails.arrow.offsetWidth / 2);
6400
6401 //the max position the thumbnail preview can be before we need to compensate to keep it visible in the player visible area
6402 var thumbnailsMaxRightPosition = this.seekBarElement.getBoundingClientRect().width - this.thumbnails.container.offsetWidth;
6403
6404 //now we compensate when the thumbnails preview is leaving the screen
6405 //if leaving on the left side
6406
6407 // WARN: magic number, offsets between seekBar and player borders
6408 var seekBarHorizontalMargins = 15;
6409
6410 if (centeredPosition < -1 * seekBarHorizontalMargins) {
6411 var offset = Math.abs(centeredPosition);
6412
6413 var finalPosition = centeredPosition + offset - seekBarHorizontalMargins;
6414 var arrowFinalPosition = arrowCenteredPosition - offset + seekBarHorizontalMargins;
6415 //if leaving on the right side
6416 } else if (centeredPosition > thumbnailsMaxRightPosition + seekBarHorizontalMargins) {
6417 var offset = Math.abs(thumbnailsMaxRightPosition - centeredPosition);
6418
6419 var finalPosition = centeredPosition - offset + seekBarHorizontalMargins;
6420 var arrowFinalPosition = arrowCenteredPosition + offset - seekBarHorizontalMargins;
6421 } else {
6422 var finalPosition = centeredPosition;
6423 var arrowFinalPosition = arrowCenteredPosition;
6424 }
6425
6426 //NOW THAT CALCULATION ARE DONE, WE PLACE THE ELEMENTS
6427 //align with mouse
6428 this.thumbnails.container.style.left = finalPosition + 15 + 'px'
6429 //aligning the arrow
6430 this.thumbnails.arrow.style.left = arrowFinalPosition + 'px';
6431
6432 // used to display thumbnails popup after image load
6433 this.lastMouseEvent = e;
6434 this.mousePosition = position;
6435 },
6436
6437 //has it's own function since multiple thing use this calculation.
6438 calculateSeekbarMousePositionFromEvent: function(e, seekBarBound) {
6439 if (!e) return;
6440 var pageX;
6441 // touchstart array
6442 if (e.touches && e.touches.length) {
6443 pageX = e.touches[0].pageX
6444 // touchmove / touchend array, touches arr could be empty at this point
6445 } else if (e.changedTouches && e.changedTouches.length) {
6446 pageX = e.changedTouches[0].pageX
6447 } else {
6448 pageX = e.pageX;
6449 }
6450 var position = pageX - (seekBarBound.left + window.pageXOffset + (this.seekBarHandleWidth / 2)),
6451 range = seekBarBound.width - this.seekBarHandleWidth;
6452
6453 if (position > range) position = range;
6454 if (position < 0) position = 0;
6455
6456 return {
6457 position: position,
6458 range: range
6459 };
6460 },
6461
6462 // API method
6463 enableSizeToggle: function() {
6464 this.cinemaModeBtn.style.display = 'block';
6465 },
6466
6467 disableSizeToggle: function() {
6468 this.cinemaModeBtn.style.display = 'none';
6469 },
6470
6471 enableTopBar: function() {
6472 this.topBar.style.display = 'block';
6473 this.topBarVisible = true; // used to choose the right shareBtn to show
6474 if (this.shareBtnVisible) {
6475 this.enableShareBtn();
6476 }
6477 },
6478
6479 disableTopBar: function() {
6480 this.topBar.style.display = 'none';
6481 this.topBarVisible = false;
6482 if (this.shareBtnVisible) {
6483 this.enableShareBtn();
6484 }
6485 },
6486
6487 enableShareBtn: function() {
6488 this.disableShareBtn(); // hide both buttons
6489 this.shareBtn.style.display = 'block';
6490 this.shareBtnVisible = true; // used to enable shareBtn on showing topBar
6491 },
6492
6493 disableShareBtn: function() {
6494 this.shareBtn.style.display = 'none';
6495 this.shareBtnVisible = false;
6496 },
6497
6498 enableCinemaModeBtn: function() {
6499 this.cinemaModeBtn.style.display = 'block';
6500 },
6501
6502 disableCinemaModeBtn: function() {
6503 this.cinemaModeBtn.style.display = 'none';
6504 },
6505
6506 enableFullscreenBtn: function() {
6507 this.fullscreenBtn.style.display = 'block';
6508 },
6509
6510 disableFullscreenBtn: function() {
6511 this.fullscreenBtn.style.display = 'none';
6512 },
6513
6514 enableChromecastBtn: function() {
6515 this.chromecastBtn.style.display = 'block';
6516 },
6517
6518 disableChromecastBtn: function() {
6519 this.chromecastBtn.style.display = 'none';
6520 },
6521
6522 enableAutoplayOption: function() {
6523 this.optionsAutoplay.style.display = 'block';
6524 },
6525
6526 disableAutoplayOption: function() {
6527 this.optionsAutoplay.style.display = 'none';
6528 },
6529
6530 enableOptions: function() {
6531 this.optionsContainer.style.display = 'block';
6532 },
6533
6534 disableOptions: function() {
6535 this.optionsContainer.style.display = 'none';
6536 },
6537
6538 showOptions: function() {
6539 addClass(this.optionsContainer, 'menu');
6540 this.optionsVisible = true;
6541 },
6542
6543 hideOptions: function() {
6544 removeClass(this.optionsContainer, 'menu');
6545 this.optionsVisible = false;
6546 },
6547
6548 initContextMenu: function() {
6549 var self = this,
6550 player = this.player,
6551 context = this.elements.contextMenu;
6552
6553 this.contextMenu = xest(context.container);
6554
6555 this.hideContextMenu();
6556 // one place to rule them all
6557 document.body.addEventListener('contextmenu', function(e) {
6558 var el = e.target;
6559
6560 // all player controls have this prefix
6561
6562 // SVG tags (hotspots bar for example) DO HAVE classNames
6563 // but they are complex objects and not a regular html classes
6564
6565 if (!el.className.indexOf || el.className.indexOf('mhp1138') !== -1) {
6566 // digging thru the DOM tree to get the name of the player under mouse pointer
6567 // and compare it with our name
6568 while (!el.className.indexOf || el.className.indexOf('mhp1138_container') == -1 && el.tagName != 'BODY') {
6569 el = el.parentNode;
6570 }
6571 if (el.getAttribute('id') == self.player.playerId) {
6572 self.showContextMenu(e);
6573 } else {
6574 // click doesnt belong to our player
6575 self.hideContextMenu();
6576 }
6577
6578 e.preventDefault();
6579 return false;
6580 } else {
6581 // hiding it when the user popped up native context menu outside of the player
6582 self.hideContextMenu();
6583 }
6584 });
6585
6586 this.addClickEvent(document.body, this.hideContextMenu.bind(this));
6587 this.addClickEvent(this.container, this.hideContextMenu.bind(this));
6588
6589 var copyUrlVideo = xest(context.copyUrlVideo),
6590 copyUrlVideoTime = xest(context.copyUrlVideoTime),
6591 copyEmbed = xest(context.copyEmbed),
6592 about = xest(context.about),
6593
6594 settings = this.settings,
6595 url = settings.mainRoll.videoUrl,
6596 embedUrl = settings.features.embedCode;
6597
6598 this.addClickEvent(copyUrlVideo, function() {
6599 fireEvent('copyUrlVideo');
6600
6601 if (url.length) {
6602 self.copyToClipboard(url);
6603 }
6604 //self.hideContextMenu();
6605 });
6606
6607 this.addClickEvent(copyUrlVideoTime, function() {
6608 fireEvent('copyUrlVideoTime');
6609
6610 if (url.length) {
6611 self.copyToClipboard(self.player.addCurrentTimeToUrl(url));
6612 }
6613 //self.hideContextMenu();
6614 });
6615
6616 this.addClickEvent(copyEmbed, function() {
6617 fireEvent('copyEmbed');
6618
6619 if (embedUrl.length) {
6620 self.copyToClipboard(embedUrl);
6621 }
6622
6623 //self.hideContextMenu();
6624 });
6625
6626 this.debugObj = new debugInfo(this, this.player);
6627
6628 if (about) {
6629 //about.style.display = 'none';
6630 this.addClickEvent(about, function() {
6631 self.hideContextMenu();
6632 self.debugObj.showVersionsMenu();
6633 });
6634 }
6635 },
6636
6637 showContextMenu: function(event) {
6638 // our context menu is useless in Safari, since it doesnt support
6639 // clipboard manipulations to copypaste video URLs
6640 if (MHP1138.detector.isSafari() && !MHP1138.detector.isChrome()) return false;
6641 // WARN: Broken safari detection in 3.0.0 branch
6642 this.contextMenuShown = true;
6643
6644 var menu = this.contextMenu,
6645 menuRect = menu.getBoundingClientRect(),
6646 playerRect = this.container.getBoundingClientRect(),
6647 menuLeft = event.clientX - playerRect.left,
6648 menuTop = event.clientY - playerRect.top;
6649
6650 if (menuLeft + menuRect.width > playerRect.width) {
6651 menuLeft -= menuRect.width;
6652 }
6653 if (menuTop + menuRect.height > playerRect.height) {
6654 menuTop -= menuRect.height;
6655 }
6656 menu.style.top = menuTop + 'px';
6657 menu.style.left = menuLeft + 'px';
6658 removeClass(menu, 'hidden');
6659 },
6660
6661 hideContextMenu: function() {
6662 this.contextMenuShown = false;
6663 addClass(this.contextMenu, 'hidden');
6664 },
6665
6666 //HIDE THE CONTROLS
6667 initAutoHideControls: function() {
6668 var self = this,
6669 container = this.container,
6670 player = this.player;
6671
6672 this.controlsBar = xest(this.elements.controls.container);
6673
6674 // local wrapper
6675 function clearHideControlsTimer(e) {
6676 self.clearHideControlsTimer();
6677 if (!self.seekBarMouseDown && !self.volumeBarMouseDown) {
6678 e.stopPropagation();
6679 }
6680 }
6681
6682 this.controlsBar.addEventListener('mousemove', clearHideControlsTimer);
6683 this.controlsBar.addEventListener('mouseout', this.startHideControlsTimer.bind(this));
6684 this.topBar.addEventListener('mousemove', clearHideControlsTimer);
6685 this.shareBtn.addEventListener('mousemove', clearHideControlsTimer);
6686 this.seekBarContainer.addEventListener('mousemove', clearHideControlsTimer);
6687 if (this.hotspotsContainer) {
6688 this.hotspotsContainer.addEventListener('mousemove', clearHideControlsTimer);
6689 }
6690
6691 container.addEventListener('mouseover', this.showControls.bind(this));
6692 container.addEventListener('mousemove', function(e) {
6693 if (!self.filterChromeMouseMoves(e)) {
6694 self.showControls();
6695 }
6696 });
6697 container.addEventListener('touchstart', clearHideControlsTimer);
6698 container.addEventListener('touchmove', clearHideControlsTimer);
6699 container.addEventListener('touchend', this.startHideControlsTimer.bind(this));
6700
6701 // disable emulated mouse events generation after bubbling
6702 this.controlsBar.addEventListener('touchend', function(e) {
6703 e.preventDefault();
6704 });
6705 },
6706
6707 // Chrome has weird behaviour about repeatedly firing mousemove events (every 16-33ms)
6708 // with the SAME coords trying to get focus on its window
6709 // (Windows only issue)
6710 filterChromeMouseMoves: function(e) {
6711 if (this.chromeActiveBug &&
6712 this.chromeActiveBug.x == e.pageX &&
6713 this.chromeActiveBug.y == e.pageY
6714 ) {
6715 return true;
6716 }
6717
6718 this.chromeActiveBug = {
6719 x: e.pageX,
6720 y: e.pageY
6721 }
6722 return false;
6723 },
6724
6725 clearHideControlsTimer: function() {
6726 clearTimeout(this.hideControlsTimer);
6727 },
6728
6729 startHideControlsTimer: function() {
6730 this.clearHideControlsTimer();
6731 if (!this.seekBarMouseDown && !this.volumeBarMouseDown) {
6732 this.hideControlsTimer = setTimeout(this.hideAllControls.bind(this), this.settings.features.hideControlsTimeout * 1000);
6733 }
6734 },
6735
6736 hideAllControls: function() {
6737 //desktop embed :- show controls till the video is played
6738 //tablet embed :- shows controls always, if not then unable to play video once paused as trying to show controls by tapping will redirect user
6739 if((this.settings.embeds.enabled && (!this.player.videoStarted || isTablet)) || (isTablet && this.player.preRoll.enabled)) return false;
6740
6741 this.hideControls();
6742 this.hideOptions();
6743 this.hideSeekBarHandle();
6744 },
6745
6746 hideControls: function() {
6747 if (!this.hiddenControls) {
6748 addClass(this.container, 'hideControls');
6749 }
6750 this.hiddenControls = true;
6751 this.controlsShownByTouch = false;
6752 },
6753
6754 showControls: function(touchFlag) {
6755 var self = this;
6756
6757 removeClass(this.container, 'hideControls');
6758 this.startHideControlsTimer();
6759 // waiting for the end of current execution context
6760 // and controls bar animation to prevent thumbnail preview bubbling
6761 setTimeout(function() {
6762 self.hiddenControls = false;
6763 }, 200);
6764
6765 // no autohide on touch events
6766 if (touchFlag) {
6767 this.controlsShownByTouch = true;
6768 }
6769 },
6770
6771 //TOOLTIPS
6772 initTooltips: function() {
6773 var self = this,
6774 elements = zest('#' + this.player.playerId + ' [title]'),
6775 tooltip = this.elements.tooltip,
6776 i = 0, text;
6777
6778 this.tooltip = xest(tooltip.container);
6779 this.tooltipTitle = xest(tooltip.title);
6780 this.tooltipArrow = xest(tooltip.arrow);
6781 this.tooltipArrowRect = this.tooltipArrow.getBoundingClientRect();
6782
6783 for(; i < elements.length; i++) {
6784 text = elements[i].getAttribute('title');
6785 this.setTooltipText(elements[i], text);
6786 this.bindTooltipEvents(elements[i]);
6787 // removing default HTML tooltips
6788 elements[i].removeAttribute('title');
6789 }
6790 },
6791
6792 bindTooltipEvents: function(element) {
6793 var self = this;
6794
6795 element.addEventListener('mouseenter', function() {
6796 self.showTooltip(this);
6797 });
6798
6799 element.addEventListener('mouseleave', function() {
6800 self.hideTooltip();
6801 });
6802 },
6803
6804 setTooltipText: function(element, text) {
6805 element.tooltipText = text;
6806 },
6807
6808 showTooltip: function(element, text) {
6809 if (element.tooltipDisabled || this.hiddenControls) {
6810 return false;
6811 }
6812
6813 this.tooltipTitle.innerHTML = element.tooltipText;
6814
6815 // tooltip position override could be enabled
6816 // by setting one of these values: [top,left,bottom,right]
6817 var positionOverride = element.getAttribute('tooltipPosition');
6818
6819 var elementRect = element.getBoundingClientRect(),
6820 playerRect = this.container.getBoundingClientRect(),
6821 elementLeft = elementRect.left - playerRect.left + elementRect.width / 2,
6822 elementTop = elementRect.top - playerRect.top,
6823 tooltipWidth = this.tooltip.offsetWidth,
6824 tooltipHeight = this.tooltip.offsetHeight + this.tooltipArrow.offsetHeight - 4, // magic number, additional space between element and tooltip
6825 tooltipLeft = elementLeft - tooltipWidth / 2,
6826 tooltipTop = elementTop - tooltipHeight,
6827 tooltipArrowLeft;
6828
6829 if (tooltipLeft - this.tooltipMinimalBounds < 0) {
6830 tooltipLeft = this.tooltipMinimalBounds;
6831 tooltipArrowLeft = elementLeft - this.tooltipMinimalBounds;
6832 } else if (tooltipLeft + tooltipWidth - playerRect.width - this.tooltipMinimalBounds > 0) {
6833 tooltipLeft = playerRect.width - this.tooltipMinimalBounds - tooltipWidth;
6834 tooltipArrowLeft = elementLeft - tooltipLeft;
6835 } else {
6836 tooltipArrowLeft = tooltipWidth / 2;
6837 }
6838
6839 if ((tooltipTop - this.tooltipMinimalBounds < 0 || positionOverride == 'bottom') &&
6840 positionOverride != 'top'
6841 ) {
6842 tooltipTop = elementTop + elementRect.height + this.tooltipArrow.offsetHeight + 2;
6843 addClass(this.tooltip, 'topDown');
6844 } else {
6845 removeClass(this.tooltip, 'topDown');
6846 }
6847
6848 if (positionOverride == 'left' || positionOverride == 'right') {
6849 tooltipTop = elementTop + (elementRect.height - this.tooltip.offsetHeight) / 2;
6850 } else {
6851 // add offset to centered arrow position for controls squashed to player borders
6852 this.tooltipArrow.style.left = tooltipArrowLeft + 'px';
6853 }
6854
6855 if (positionOverride == 'left') {
6856 addClass(this.tooltip, 'leftSided');
6857 tooltipLeft = elementRect.left - playerRect.left - tooltipWidth - 11; // magic number, tooltip arrow width + some spacing
6858 this.tooltipArrow.style.left = '100%';
6859 } else {
6860 removeClass(this.tooltip, 'leftSided');
6861 }
6862
6863 if (positionOverride == 'right') {
6864 tooltipLeft = elementRect.left - playerRect.left + elementRect.width + 11;
6865 addClass(this.tooltip, 'rightSided');
6866 this.tooltipArrow.style.left = 0;
6867 } else {
6868 removeClass(this.tooltip, 'rightSided');
6869 }
6870
6871 this.tooltip.style.left = tooltipLeft + 'px';
6872 this.tooltip.style.top = tooltipTop + 'px';
6873
6874 removeClass(this.tooltip, 'hidden');
6875 },
6876
6877 hideTooltip: function() {
6878 addClass(this.tooltip, 'hidden');
6879 },
6880
6881 enableTooltip: function(element) {
6882 element.tooltipDisabled = false;
6883 },
6884
6885 disableTooltip: function(element) {
6886 element.tooltipDisabled = true;
6887 },
6888
6889 disableTooltips: function() {
6890 this.tooltip.style.display = 'none';
6891 },
6892
6893 enableTooltips: function() {
6894 this.tooltip.style.display = 'block';
6895 },
6896
6897 delayTooltip: function(element, delay) {
6898 var self = this;
6899 this.disableTooltip(element);
6900 var delayedAction = __.debounce(function() {
6901 self.enableTooltip(element);
6902 }, delay);
6903 delayedAction();
6904 },
6905
6906 filterFeatures: function(features) {
6907 if (features.tooltips) {
6908 this.enableTooltips();
6909 } else {
6910 this.disableTooltips();
6911 }
6912
6913 if (features.logo) {
6914 this.enableLogo();
6915 } else {
6916 this.disableLogo();
6917 }
6918
6919 if (features.mute) {
6920 this.enableVolumeBtn();
6921 } else {
6922 this.disableVolumeBtn();
6923 }
6924
6925 if (features.volumeBar) {
6926 this.enableVolumeBar();
6927 } else {
6928 this.disableVolumeBar();
6929 }
6930
6931 if (features.options ||
6932 features.optionsEnabled
6933 ) {
6934 this.enableOptions();
6935 } else {
6936 this.disableOptions();
6937 }
6938
6939 if (features.showAutoplayOption
6940 ) {
6941 this.enableAutoplayOption();
6942 } else {
6943 this.disableAutoplayOption();
6944 }
6945
6946 if (features.cinema ||
6947 features.playerSizeToggle
6948 ) {
6949 this.enableCinemaModeBtn();
6950 } else {
6951 this.disableCinemaModeBtn();
6952 }
6953
6954 if (features.fullscreen) {
6955 this.enableFullscreenBtn();
6956 } else {
6957 this.disableFullscreenBtn();
6958 }
6959
6960 if (features.share ||
6961 features.shareBtn ||
6962 features.shareBar
6963 ) {
6964 this.enableShareBtn();
6965 } else {
6966 this.disableShareBtn();
6967 }
6968
6969 if (features.title ||
6970 features.topBar ||
6971 features.topControlBar
6972 ) {
6973 this.enableTopBar();
6974 } else {
6975 this.disableTopBar();
6976 }
6977 },
6978
6979 //UTILITY
6980 pixelToPercent: function(pixel, range){
6981 return ((pixel * 100) / range);
6982 },
6983
6984 percentToPixel: function(percentage, range){
6985 return ((percentage * range) / 100);
6986 },
6987
6988 copyToClipboard: function(string) {
6989 var range = document.createRange(),
6990 selection,
6991 success;
6992
6993 // IE
6994 if (window.clipboardData) {
6995 window.clipboardData.setData('Text', string);
6996 } else {
6997 // Create a temporary element off screen.
6998 var tempElement = document.createElement('div');
6999
7000 tempElement.innerText = string;
7001 tempElement.style.position = 'absolute';
7002 tempElement.style.userSelect = 'text';
7003 tempElement.style.webkitUserSelect = 'text';
7004 tempElement.style.mozUserSelect = 'text';
7005 tempElement.style.top = '-1000px';
7006 tempElement.style.left = '-1000px';
7007 document.body.appendChild(tempElement);
7008
7009 // Select temp element
7010 range.selectNodeContents(tempElement);
7011 selection = window.getSelection();
7012 selection.removeAllRanges();
7013 selection.addRange(range);
7014
7015 // Lets copy
7016 try {
7017 document.execCommand('copy', false, null);
7018 } catch (e) {
7019 console.warn('copy to clipboard failed', e);
7020 }
7021 document.body.removeChild(tempElement);
7022 }
7023 }
7024 };
7025}
7026
7027(function(window, _) {
7028 'use strict';
7029
7030 var L10n = function(locales, language) {
7031 var defaultLanguage = 'en';
7032
7033 var systemLanguage = (function() {
7034 // works for IE / Safari / Chrome / Firefox
7035 var language = window.navigator.userLanguage || window.navigator.language;
7036 // trim it to prefix only (en-US, en-GB, etc)
7037 return language.substr(0, 2);
7038 })();
7039
7040 if (!language || language === 'auto') {
7041 language = systemLanguage;
7042 }
7043
7044 return {
7045 defaultLanguage: defaultLanguage,
7046 systemLanguage: systemLanguage,
7047 language: language,
7048 localize: function(string, forceLanguage) {
7049 var l = language;
7050 if (forceLanguage) {
7051 l = forceLanguage.substr(0,2);
7052 }
7053 var matches = string.match(/(%\S+%)/g);
7054 _.each(matches, function(match) {
7055 var replacement;
7056 if (locales[l] && locales[l][match]) {
7057 replacement = locales[l][match].replace(new RegExp('(\')', 'g'), '’');
7058 }
7059 if (!replacement) {
7060 //removeIf(production)
7061 window.MHP1138.error('Missing ' + match + ' replacement for "' + l + '" locale');
7062 //endRemoveIf(production)
7063 replacement = locales[defaultLanguage][match];
7064 }
7065 if (replacement) {
7066 string = string.replace(match, replacement);
7067 } else {
7068 //removeIf(production)
7069 window.MHP1138.error('Missing ' + match + ' replacement for "' + defaultLanguage + '" locale');
7070 //endRemoveIf(production)
7071 }
7072 });
7073 return string;
7074 }
7075 };
7076 };
7077
7078 window.MHP1138 = window.MHP1138 || {};
7079 window.MHP1138.L10n = L10n;
7080})(window, __);
7081(function(window, _) {
7082 'use strict';
7083
7084 /**
7085 * Thumbnails preloader
7086 *
7087 * @param {float} duration Video duration
7088 * @param {object} settings Video thumbnails settings (part of the global player settings from mainRoll section)
7089 * @param {function} subscribeToEvent Custom event handler from the player package
7090 */
7091
7092 var ThumbnailsLoader = function(duration, settings, subscribeToEvent) {
7093 var thumbnailsRegex = /{(\d+)}/,
7094 sheets = [],
7095 thumbnails = [],
7096 //thumbnails from centro are always have width = 168px, just to be safe
7097 centroThumbnailsWidth = 168,
7098 samplingFrequency,
7099 slides;
7100
7101 function init(settings) {
7102 var sheetFormat = null,
7103 pattern = settings.urlPattern,
7104 columns = 1,
7105 rows = 1,
7106 count = 1,
7107 url;
7108
7109 if (!pattern.length) {
7110 return;
7111 }
7112
7113 samplingFrequency = parseInt(settings.samplingFrequency, 10);
7114
7115 if (settings.cdnType == 'centro') {
7116 if (!duration) {
7117 //removeIf(production)
7118 window.MHP1138.error('ThumbnailsLoader: no mainRoll video duration available');
7119 //endRemoveIf(production)
7120 }
7121
7122 slides = parseInt(duration / settings.samplingFrequency, 10);
7123 if (slides) {
7124 columns = slides + 1; // +1 last slide
7125 rows = 1;
7126 settings.thumbWidth = centroThumbnailsWidth;
7127 } else {
7128 return;
7129 }
7130 } else {
7131 sheetFormat = settings.format.split('x');
7132 columns = parseInt(sheetFormat[0], 10);
7133 rows = parseInt(sheetFormat[1], 10);
7134
7135 // TODO: add automatic calculation of thumbs sheet dimensions
7136 if (sheetFormat.length != 2 ||
7137 _.isNaN(columns) ||
7138 _.isNaN(rows)
7139 ) {
7140 //removeIf(production)
7141 //the thumbnails format is not valid
7142 window.MHP1138.error('ThumbnailsLoader: format (' + settings.format + ') is not valid');
7143 //endRemoveIf(production)
7144 return;
7145 }
7146
7147 var match = pattern.match(thumbnailsRegex);
7148 if (match === null) {
7149 //removeIf(production)
7150 //the urlPatern is not valid
7151 window.MHP1138.error('ThumbnailsLoader: urlPattern is not valid');
7152 //endRemoveIf(production)
7153 return;
7154 }
7155
7156 count = parseInt(match[1], 10) + 1;
7157 if (isNaN(count) || count === 0) {
7158 return;
7159 }
7160 }
7161
7162 for (var i = 0; i < count; i++) {
7163 if (settings.cdnType == 'centro') {
7164 url = pattern;
7165 } else {
7166 url = pattern.replace(thumbnailsRegex, i);
7167 }
7168
7169 sheets[i] = {
7170 index: i,
7171 url: url,
7172 thumbWidth: settings.thumbWidth,
7173 thumbHeight: settings.thumbHeight,
7174 width: settings.thumbWidth * columns,
7175 height: settings.thumbHeight * rows,
7176 cached: false,
7177 ready: false, // the state of sheet when its ready to display (but COULD be not fully loaded yet)
7178 loaded: false,
7179 error: false,
7180 cdnType: settings.cdnType
7181 };
7182 }
7183
7184 //register each thumbs position to an array.. this take ~0.076ms, so it's super fast.
7185 var tbCount = 0;
7186 for (var sheet = 0; sheet < count; sheet++) {
7187 for (var row = 0; row < rows; row++) {
7188 for (var col = 0; col < columns; col++) {
7189 thumbnails[tbCount] = {
7190 index: tbCount,
7191 sheet: sheet,
7192 row: row,
7193 col: col,
7194 cssLeft: -1 * col * settings.thumbWidth + 'px',
7195 cssTop: -1 * row * settings.thumbHeight + 'px'
7196 };
7197 tbCount++;
7198 }
7199 }
7200 }
7201 }
7202
7203 function preload(async) {
7204 // getting index of the first not cached sheet
7205 for (var i = 0; i < sheets.length; i++) {
7206 if (!sheets[i].cached) {
7207 if (async) {
7208 // load them all
7209 cacheSpritesheet(sheets[i]);
7210 } else {
7211 // use callback to load sheets one by one
7212 cacheSpritesheet(sheets[i], preload);
7213 break;
7214 }
7215 }
7216 }
7217 }
7218
7219 function cacheSpritesheet(sheet, callback) {
7220 var img = document.createElement('img'),
7221 sheetFormat = settings.format.split('x'),
7222 columns = parseInt(sheetFormat[0], 10),
7223 rows = parseInt(sheetFormat[1], 10);
7224
7225 img.onload = function() {
7226 sheet.loaded = true;
7227 sheet.ready = true;
7228
7229 // 404 image has different dimensions
7230 if (sheet.cdnType != 'centro' &&
7231 (this.naturalWidth != sheet.width ||
7232 this.naturalHeight != sheet.height)
7233 ) {
7234 sheet.width = this.naturalWidth;
7235 sheet.height = this.naturalHeight;
7236 sheet.thumbWidth = this.naturalWidth / columns;
7237 sheet.thumbHeight = this.naturalHeight / rows;
7238
7239 // Before it was an error
7240 // ToDo: we need to notify about wrong file size somehow
7241 // sheet.error = true;
7242 }
7243
7244 // img.src is always the absolute url, while the sheet.url could be relative (ex: "/videos/12342523/S3.jpg")
7245 // updating it
7246 sheet.url = img.src;
7247
7248 if (callback) { callback(); }
7249 };
7250
7251 img.onerror = function() {
7252 sheet.error = true;
7253
7254 if (callback) { callback(); }
7255 };
7256
7257 img.src = sheet.url;
7258 sheet.cached = true;
7259 sheet.image = img;
7260
7261 if (settings.progressive && callback) {
7262 watchSheetData(img, sheet, callback);
7263 }
7264 }
7265
7266 /**
7267 * watch for image dimensions availability BEFORE its full load
7268 * could save some seconds on slow connections when using progressive jpegs
7269 *
7270 * @param {DOMElement} img
7271 * @param {object} sheet
7272 * @param {function} callback
7273 */
7274
7275 function watchSheetData(img, sheet, callback) {
7276 if (img.naturalWidth > 0 &&
7277 img.naturalHeight > 0
7278 ) {
7279 sheet.ready = true;
7280
7281 callback();
7282 }
7283
7284 if (!sheet.loaded &&
7285 !sheet.ready &&
7286 !sheet.error
7287 ) {
7288 setTimeout(function() {
7289 watchSheetData(img, sheet);
7290 }, 100);
7291 }
7292 }
7293
7294 /*
7295 * There are two ways to use this method.
7296 * You can call it with seconds argument only and instantly get thumbnail info or false if it isnt loaded yet
7297 * OR
7298 * You can also specify callback function, and get thumbnail info when its spritesheet would be loaded
7299 * (or error if not).
7300 *
7301 * @param {float} seconds Video timeline position
7302 * @param {function} callback Callback function with 3 arguments: thumbnail, spritesheet, error
7303 */
7304
7305 function get(seconds, callback) {
7306 var index = Math.floor(seconds / samplingFrequency),
7307 thumbnail = thumbnails[index],
7308 sheet;
7309
7310 if (!thumbnail) {
7311 // no thumbnail for this time, instant error callback
7312 if (callback) { callback(false, false, { error: 'out of time' }); }
7313 return false;
7314 } else {
7315 // checking whatever it is available or should be loaded first
7316 sheet = sheets[thumbnail.sheet];
7317
7318 if (sheet) {
7319 if (sheet.error) {
7320 if (callback) { callback(false, false, { error: 'error loading spritesheet' }); }
7321 return false;
7322 } else if (!sheet.cached) {
7323 // preload spritesheet
7324 cacheSpritesheet(sheet, function() {
7325 //console.log('preloaded', sheet);
7326 if (callback) { callback(thumbnail, sheet); }
7327 });
7328 return false;
7329 } else if (sheet.ready) {
7330 // spritesheet is ready
7331 if (callback) { callback(thumbnail, sheet); }
7332 return {
7333 thumbnail: thumbnail,
7334 sheet: sheet
7335 };
7336 }
7337 } else {
7338 // no sheet data provided for thumbnail
7339 // unrealistic scenario if the generator did it right
7340 return false;
7341 }
7342 }
7343 return false;
7344 }
7345
7346 init(settings);
7347
7348 if (settings.preload) {
7349 subscribeToEvent('onVideoReady', function() {
7350 preload(settings.async);
7351 });
7352 }
7353
7354 return {
7355 preload: preload,
7356 sheets: sheets,
7357 thumbnails: thumbnails,
7358 get: get,
7359 settings: settings,
7360 samplingFrequency: samplingFrequency,
7361 slides: slides
7362 };
7363 };
7364
7365 window.MHP1138 = window.MHP1138 || {};
7366 window.MHP1138.ThumbnailsLoader = ThumbnailsLoader;
7367})(window, __);
7368function mhp1138_playerPlugin_HTML5Player() {
7369 var l,
7370 fireEvent,
7371 subscribeToEvent,
7372 browser = MHP1138.detector.getBrowser(),
7373 isIos = MHP1138.detector.isIos(),
7374 isIosTablet = isIos && browser.type == "tablet",
7375 isIosSafari = (isIos && (browser.name == 'safari' || browser.name == 'ios')),
7376 // shortcuts for the most used underscore functions
7377 each = __.each,
7378 deepExtend = __.deepExtend,
7379 isPath = __.isPath;
7380
7381 return {
7382 settings: {},
7383 playerType: 'HTML5Player',
7384 chromecast: {},
7385 skin: {},
7386 volume: 100,
7387 muted: false,
7388 viewedSeconds: 0,
7389 viewingStart: 0,
7390 viewedTimeout: null,
7391 isReady: false,
7392
7393 markup: {
7394 video: '<video <%= attributes %>><%= source %></video>',
7395 virtualVideo: '<canvas>This feature is not supported on your browser!</canvas><video crossorigin="anonymous" <%= attributes %>><%= source %></video>',
7396 source: '<source src="<%= link %>" type="video/mp4" />'
7397 },
7398
7399 initPlayer: function(id, settings) {
7400 var self = this;
7401 // shortcut with local this
7402 fireEvent = function(eventName, params) {
7403 return __.fireEvent(self, eventName, params);
7404 };
7405 // localizing + proxifying global function
7406 subscribeToEvent = function(eventName, callback) {
7407 return MHP1138.player.subscribeToEvent(eventName, id, callback);
7408 };
7409
7410
7411 settings = this.overrideInitSettings(settings);
7412 settings = this.overrideEmbedSettings(settings);
7413 settings = this.overrideTabletSettings(settings);
7414 settings = this.overrideMobileSettings(settings);
7415 settings = this.overrideSafariSettings(settings);
7416 settings = this.supportDeprecatedSettings(settings);
7417 settings = this.supportDefaultOverlayTextAd(settings);
7418
7419 if (MHP1138.L10n && MHP1138.Locales) {
7420 var langsPack = MHP1138.Locales;
7421 if (settings.extendedLocales) {
7422 deepExtend(langsPack, settings.extendedLocales);
7423 }
7424 this.l10n = new MHP1138.L10n(langsPack, settings.locale);
7425 // shortcut
7426 l = this.l10n.localize;
7427 }
7428
7429 this.settings = settings;
7430 this.playerId = id;
7431
7432 this.loadSkin();
7433 this.createInstanceOfSkin();
7434 this.createPlayer();
7435 },
7436
7437 loadSkin: function() {
7438
7439 if (!document.getElementById('mhp1138_skin')) {
7440 var skinContainer = document.createElement('div'),
7441 head = document.head,
7442 body = document.body;
7443 skinContainer.id = 'mhp1138_skin';
7444 skinContainer.style.display = 'none';
7445
7446 //Skin styles
7447 if (MHP1138.skinsMarkup['css']) {
7448 var stylesElement = document.createElement('style');
7449
7450 //Firefox don't support innerText..
7451 // stylesElement.innerText = stylesElement.textContent = MHP1138.skinsMarkup['css'];
7452 stylesElement.innerHTML = MHP1138.skinsMarkup['css'];
7453 head.appendChild(stylesElement);
7454 } else {
7455 //removeIf(production)
7456 //if the skin compiled wrong way
7457 MHP1138.error('You are missing skin styles');
7458 //endRemoveIf(production)
7459 return;
7460 }
7461
7462 //Skin template
7463 if (MHP1138.skinsMarkup['html']) {
7464 skinContainer.innerHTML = MHP1138.skinsMarkup['html'];
7465 } else {
7466 //removeIf(production)
7467 //if the skin compiled wrong way
7468 MHP1138.error('You are missing skin template');
7469 //endRemoveIf(production)
7470 return;
7471 }
7472
7473 // compile and store player markup for the first time in globally accessible variable
7474 if (MHP1138.markup && !MHP1138.skinsMarkup['markup']) {
7475 this.compileSkinMarkup();
7476 }
7477 body.insertBefore(skinContainer, body.firstChild);
7478 }
7479 },
7480
7481 compileSkinMarkup: function() {
7482 var compiledMarkup = __.toMarkup(MHP1138.markup, 'mhp1138_');
7483
7484 if (this.l10n) {
7485 compiledMarkup = l(compiledMarkup);
7486 };
7487
7488 MHP1138.skinsMarkup['markup'] = compiledMarkup;
7489 },
7490
7491 createInstanceOfSkin: function() {
7492 this.skin = window['mhp1138_skin']();
7493
7494 this.skin.elements = __.addPrefixToSkinElements(
7495 MHP1138.selectors,
7496 'mhp1138',
7497 this.playerId
7498 );
7499
7500 if (__.isArray(MHP1138.themeCss)) {
7501 var themeCss = __.addPrefixAndColorToSkinThemeCss(
7502 MHP1138.themeCss,
7503 'mhp1138',
7504 this.playerId,
7505 this.settings.features.themeColor
7506 ),
7507 themeCssNode = document.createElement('style'),
7508 head = document.head;
7509
7510 themeCssNode.innerHTML = themeCss.join('\n');
7511 head.appendChild(themeCssNode);
7512 }
7513
7514 MHP1138.loadedMasterCSS = true;
7515 },
7516
7517 setOverlays: function(overlays) {
7518 this.overlays = overlays;
7519 this.skin.deleteOverlays();
7520 this.skin.createOverlays();
7521 },
7522
7523
7524 getSourceForMainRoll: function() {
7525 var mainRoll = this.mainRoll;
7526
7527 // parse mediaDefinition and create quality arrays for internal use
7528 if (mainRoll.mediaDefinition.length) {
7529 // update sources in mediaDefinition object
7530 this.mainRoll.mediaDefinition = this.filterMediaSources(mainRoll.mediaDefinition);
7531 this.getStoredQuality();
7532
7533 return this.videoSources[this.selectedResolution];
7534
7535 // no mediaDefinitions but just one video url provided
7536 } else if (isPath(mainRoll.videoUrl)) {
7537 return mainRoll;
7538 } else {
7539 return '';
7540 }
7541 },
7542
7543 createPlayer: function() {
7544 var self = this,
7545 settings = this.settings,
7546 mainRoll = settings.mainRoll;
7547
7548 this.playing = false;
7549 this.videoEnded = false;
7550 this.videoStarted = false;
7551 this.fullscreen = false;
7552 this.isPreRollActive = false;
7553 this.currentTime = 0.0;
7554
7555 // if the web site want us to act like the video is unavailable
7556 // for some reason.
7557 if (mainRoll.videoUnavailable ||
7558 mainRoll.videoUnavailableMessage.length
7559 ) {
7560 this.videoNotAvailable();
7561 return;
7562 }
7563
7564 this.mainRoll = mainRoll;
7565
7566 var source = this.getSourceForMainRoll(),
7567 sourceUrl = (source && source.videoUrl) ? source.videoUrl : '';
7568
7569 this.initVastParser();
7570 this.initPreRoll();
7571 this.initPauseRoll();
7572
7573 // init video player with preRoll source instead of the main one
7574 if (this.preRoll.enabled &&
7575 isPath(this.preRoll.videoUrl)
7576 ) {
7577 sourceUrl = this.preRoll.videoUrl;
7578 }
7579
7580 // create main controls
7581 this.initContainer();
7582
7583 if (!sourceUrl) {
7584 //removeIf(production)
7585 //check to be sure there is at least one valid video source
7586 MHP1138.error('You need to define at least one valid video source for the player with ID "#'+ this.playerId +'".');
7587 //endRemoveIf(production)
7588 this.videoNotAvailable();
7589 return;
7590 }
7591
7592 if (!this.preRoll.enabled) {
7593 // Do not empty sourceUrl in Safari on iOS
7594 if ((!isIosSafari && source.format == 'hls') ||
7595 source.format == 'dash'
7596 ) {
7597 // create player markup without static video source
7598 // will be replaced by run-time generated HLS source
7599 sourceUrl = '';
7600 } else {
7601 sourceUrl = this._appendUrlParams(sourceUrl, this.initSourceParams(source));
7602 }
7603 }
7604
7605 // create player markup
7606 this.createPlayerMarkup(sourceUrl);
7607
7608 if (!this.preRoll.enabled) {
7609 // Do not run init for HLS player in Safari on iOS
7610 if (!isIosSafari && source.format == 'hls') {
7611 this.initHlsPlayer(source);
7612 } else if (source.format == 'dash') {
7613 this.initDashPlayer(source);
7614 }
7615 }
7616
7617 // initialize fullscreen prior to skin to enable/disable fullscreen buttton in UI
7618 if (MHP1138.Fullscreen) {
7619 this.fullscreen = new MHP1138.Fullscreen(this, fireEvent, subscribeToEvent, isIos);
7620 // fullscreen module failed to initialize or no support
7621 if (!this.fullscreen.enabled) {
7622 this.settings.features.fullscreen = false;
7623 }
7624 } else {
7625 this.settings.features.fullscreen = false;
7626 }
7627
7628 if (MHP1138.ThumbnailsLoader) {
7629 this.thumbnails = new MHP1138.ThumbnailsLoader(mainRoll.duration, mainRoll.thumbs, subscribeToEvent);
7630 }
7631
7632 this.initSkin();
7633
7634 // get settings from localStorage
7635 if (!settings.embeds.enabled) {
7636 this.getStoredMotionRate();
7637 }
7638
7639 if (settings.hotspots.enabled) {
7640 this.getStoredHotspotsState();
7641 }
7642 this.getStoredVolume();
7643
7644 // add event handlers to player <video> tag
7645 this.bindPlayerEvents();
7646
7647 // add keyboard and fullscreen events handling at document (sic!) level
7648
7649 if (MHP1138.Keyboard) {
7650 this.keyboard = new MHP1138.Keyboard(this, this.skin, fireEvent); // player, skin, create event function
7651 }
7652
7653 // init chromecast and vr plugins if specified by settings
7654 if (MHP1138.CastPlayer && !this.settings.isVr && window.PresentationRequest) {
7655 this.chromecast = new MHP1138.CastPlayer(this, fireEvent); // player, create event function
7656 } else {
7657 this.chromecast = {};
7658 }
7659
7660 this.initVrPlayer();
7661
7662 // onReady event signals video tag existance and availability,
7663 // NOT actual video source readiness, see 'onVideoReady'
7664 this.isReady = true;
7665 fireEvent('onReady');
7666
7667 // This is tablets way. They cant automatically play videos on page load,
7668 // so we have to fake main player poster, actiontags, etc,
7669 // but start playing preRoll video on the first 'play' click
7670 if (this.preRoll.enabled && !this.autoplay) {
7671 this.deferredPreRoll = true;
7672 }
7673
7674 if (this.preRoll.enabled &&
7675 !this.deferredPreRoll
7676 ) {
7677 this.showPreRoll();
7678 } else {
7679 this.showMainRoll();
7680 }
7681
7682 // deferred seek for tablets and mobiles if set
7683 if (!MHP1138.detector.isDesktop() &&
7684 settings.startOffset
7685 ) {
7686 this.deferredStartSeek = true;
7687 return;
7688 }
7689
7690 // Seek to startOffset only if its main roll
7691 if (!this.preRoll.enabled && parseInt(settings.startOffset) > 0) {
7692 // seek and play
7693 this.seek(parseInt(settings.startOffset), true);
7694 } else if (this.autoplay) {
7695 // DASH player fires error at this moment, source isnt ready yet
7696 // We should wait for CAN_PLAY event from lib
7697 if (!this.dashSource) {
7698 // just play
7699 this.play();
7700 }
7701 }
7702 },
7703
7704 createPlayerMarkup: function(sourceUrl) {
7705 var settings = this.settings,
7706 videoTagWrapper = satisfy('.mhp1138_videoWrapper')[0],
7707 videoTagTemplate = __.template(this.markup.video),
7708 sourceTagTemplate = __.template(this.markup.source),
7709 canvasTagTemplate = __.template(this.markup.virtualVideo),
7710 attributesObj = {
7711 style:'width:100%;height:100%',
7712 preload: settings.videoPreload,
7713 class: '',//'mhp1138_is-hidden',
7714 },
7715 attributes = '',
7716 attributeName,
7717 sources = [];
7718
7719 if (settings.isVr) {
7720 attributesObj.style += ';display:none';
7721 }
7722
7723 each(attributesObj, function(value, key) {
7724 attributes += ' ' + key + '="' + value + '"';
7725 });
7726
7727 var source = sourceTagTemplate({
7728 link: sourceUrl
7729 });
7730
7731 // Check for VR video
7732 if (settings.isVr) {
7733 videoTagWrapper.innerHTML = canvasTagTemplate({
7734 attributes: attributes,
7735 source: source
7736 });
7737 } else {
7738 videoTagWrapper.innerHTML = videoTagTemplate({
7739 attributes: attributes,
7740 source: source
7741 });
7742 }
7743
7744 this.videoWrapper = this.playerContainerElement.appendChild(videoTagWrapper);
7745 this.playerElement = this.playerContainerElement.getElementsByTagName('video')[0];
7746 this.playerPoster = __.xest('#'+this.playerId+' .mhp1138_videoPoster');
7747 },
7748
7749 filterMediaSources: function(sources) {
7750 var self = this,
7751 adaptiveFlag,
7752 removeProgressiveStreams;
7753
7754 this.videoResolutions = [];
7755 this.videoSources = {};
7756
7757 each(sources, function(el) {
7758 if (el.format == 'dash' || el.format == 'hls') {
7759 if (el.quality &&
7760 el.quality.length &&
7761 isPath(el.videoUrl) // do not create anything if url failed the test
7762 ) {
7763 removeProgressiveStreams = true;
7764 each(el.quality, function(q) {
7765 sources.push({
7766 format: el.format,
7767 quality: String(q),
7768 videoUrl: el.videoUrl,
7769 params: el.params || false
7770 });
7771 });
7772 }
7773 }
7774 });
7775
7776 // sorting media array by quality in reverse order
7777 sources = __.sortBy(sources, function(el) {
7778 // Adaptive AUTO
7779 // always the first one in a list
7780 if (el.format == 'dash' && (!el.quality || typeof el.quality == 'object')) { return 9999; }
7781 if (el.format == 'hls' && (!el.quality || typeof el.quality == 'object')) { return 9998; }
7782 // converting strings like '720p48' to negative floats -720.48
7783 return -parseFloat(String(el.quality).replace(/[_p]/ig, '.')) - (el.format == 'upsell'?10000:0);
7784 });
7785
7786 // checking for valid url or upsell labels
7787 sources = __.filter(sources, function(el) {
7788 if (el.format == 'hls') {
7789 if (!window.Hls) return false;
7790 // Since we do not use HLS library do not filter hls source in Safari on iOS
7791 if (!isIosSafari && !Hls.isSupported()) return false;
7792 }
7793 if (el.format == 'dash') {
7794 if (!window.dashjs) return false;
7795 }
7796 return isPath(el.videoUrl) || el.format == 'upsell';
7797 });
7798
7799 // adaptive playlist + adaptive quality selectors is here, no need to keep MP4s
7800 if (removeProgressiveStreams) {
7801 sources = __.filter(sources, function(el) {
7802 //console.log(el);
7803 if (!el.format || el.format == 'mp4') {
7804 return false;
7805 } else {
7806 return true;
7807 }
7808 });
7809 }
7810
7811 each(sources, function(el) {
7812 var qualityName = el.quality;
7813 // adaptive stream
7814 if ((!el.quality || typeof el.quality == 'object') &&
7815 (el.format == 'dash' || el.format == 'hls')
7816 ) {
7817 qualityName = el.format;
7818 adaptiveFlag = el.format;
7819 }
7820
7821 // do not overwrite upsell elements by "secret" qualities in adaptive playlist
7822 if (!self.videoSources[qualityName]) {
7823 self.videoResolutions.push(qualityName);
7824 self.videoSources[qualityName] = el;
7825 if (el.format != 'upsell' && el.defaultQuality) {
7826 self.selectedResolution = qualityName;
7827 self.selectedFormat = el.format;
7828 }
7829 }
7830 });
7831
7832 // return us the highest resolution from the sources list
7833 // if a default one was not defined
7834 if (!this.selectedResolution) {
7835 // no defaultQuality key but choose adaptive stream as default any way
7836 if (adaptiveFlag) {
7837 this.selectedResolution = adaptiveFlag;
7838 } else {
7839 this.selectedResolution = (__.max(this.videoSources, function(el) {
7840 return parseFloat(String(el.quality).replace(/[_p]/ig, '.') * (el.format == 'upsell'?-1:1));
7841 })).quality;
7842 }
7843 }
7844
7845 // set it back to original definitions array
7846 for (var i = 0; i < sources.length;i++) {
7847 if (sources[i].quality == this.selectedResolution) {
7848 sources[i].defaultQuality = true;
7849 }
7850 }
7851
7852 return sources;
7853 },
7854
7855 initVrPlayer: function() {
7856 if (!this.settings.isVr) return;
7857 var projection,
7858 stereoType,
7859 vrVideo = this.playerContainerElement.getElementsByTagName('video')[0],
7860 vrCanvas = this.playerContainerElement.getElementsByTagName('canvas')[0],
7861 settings = this.settings;
7862
7863 __.addClass(this.playerContainerElement, 'vr');
7864
7865 switch (settings.vrProps.projection) {
7866 case 1:
7867 projection = VrPlayer.PROJECTION_EQUIDISTANT_180;
7868 break;
7869 case 2:
7870 projection = VrPlayer.PROJECTION_EQUIRECTANGULAR_360;
7871 break;
7872 case 3:
7873 projection = VrPlayer.PROJECTION_EQUIRECTANGULAR_180;
7874 break;
7875 default:
7876 throw "Invalid projection type";
7877 }
7878
7879 if (!settings.vrProps.stereoSrc) {
7880 stereoType = VrPlayer.MONO
7881 } else {
7882 switch (settings.vrProps.stereoType) {
7883 case 1:
7884 stereoType = VrPlayer.STEREO_SIDE_BY_SIDE_LR;
7885 break;
7886 case 2:
7887 stereoType = VrPlayer.STEREO_OVER_UNDER_LR;
7888 break;
7889 case 3:
7890 stereoType = VrPlayer.STEREO_SIDE_BY_SIDE_RL;
7891 break;
7892 case 4:
7893 stereoType = VrPlayer.STEREO_OVER_UNDER_RL;
7894 break;
7895 default:
7896 throw "Invalid stereo type";
7897 }
7898 }
7899
7900 try {
7901 this.vrPlayer = new VrPlayer({
7902 canvas: vrCanvas,
7903 video: vrVideo,
7904 projection: projection,
7905 stereoType: stereoType,
7906 stereoView: false
7907 });
7908
7909 var self = this;
7910
7911 // restart it every fuckin event!
7912 vrVideo.addEventListener('playing', function() {
7913 self.vrPlayer.start();
7914 });
7915
7916 vrVideo.addEventListener('seeked', function() {
7917 self.vrPlayer.start();
7918 });
7919
7920 // vrVideo.addEventListener('pause', function() {
7921 // self.vrPlayer.stop();
7922 // });
7923
7924 window.addEventListener('resize', this.vrPlayer.resize);
7925 } catch (e) {
7926 fireEvent('onVrError');
7927 }
7928 },
7929
7930 initVastParser: function() {
7931 var self = this,
7932 settings = this.settings,
7933 vastCampaigns = settings.vast
7934 settings.preRoll = settings.preRoll || [];
7935
7936 if (vastCampaigns && !__.isUndefined(MHP1138.vast)) {
7937 if(!__.isArray(vastCampaigns)) {
7938 vastCampaigns = [vastCampaigns];
7939 }
7940
7941 each(vastCampaigns, function(campaign) {
7942 var parser = new MHP1138.vast(),
7943 campaignHash = __.hashString(campaign.rollSettings.campaignName);
7944 parser.init(self, campaign, 'pre');
7945
7946 if (parser.status == 'parsed' && parser.rolls.length) {
7947
7948 // Saving rolls from vast into preRoll array
7949 settings.preRoll = settings.preRoll.concat(parser.rolls);
7950
7951 if (parser.overlays.length) {
7952 var randomBanner = parser.overlays[__.random(parser.overlays.length - 1)];
7953 self.mainRoll.overlays = [randomBanner];
7954 }
7955 } else if (parser.status == 'error') {
7956 return false;
7957 } else if (parser.status == 'loading') {
7958 // parser will manually update roll settings and re-run initAdsRoll
7959 return false;
7960 }
7961 });
7962 }
7963 },
7964
7965 videoNotAvailable: function() {
7966 this.noValidVideoSource = true;
7967 this.initSkin();
7968 this.skin.videoNotAvailable();
7969 },
7970
7971
7972 overrideInitSettings: function(settings){
7973 // Disable hotspots controls and graph if data have not been sent
7974 if(__.isEmpty(settings.hotspots.data)) {
7975 settings.hotspots.enabled = false;
7976 }
7977
7978 return settings;
7979 },
7980
7981 overrideEmbedSettings: function(settings) {
7982 // override initial settings
7983 if (settings.embeds.enabled) {
7984 deepExtend(settings, {
7985 hotspots: {
7986 enabled: false
7987 },
7988 features: {
7989 ignorePreferences: true,
7990
7991 topControlBar: true,
7992 shareBar: false,
7993 // aliases
7994 cinema: false,
7995 playerSizeToggle: false,
7996 // aliases
7997 options: false,
7998 optionsEnabled: false,
7999
8000 showHotspots: false,
8001
8002 chromecast: false
8003 }
8004 });
8005 }
8006 return settings;
8007 },
8008
8009 overrideTabletSettings: function(settings) {
8010 if (MHP1138.detector.isTablet()) {
8011 deepExtend(settings, {
8012 features: {
8013 ignorePreferences: true,
8014
8015 // aliases
8016 showAutoplayOption: false,
8017 autoplayOption: false,
8018
8019 // aliases
8020 cinema: false,
8021 playerSizeToggle: false,
8022
8023 tooltips: false,
8024 volumeBar: false,
8025 mute: false
8026 },
8027 videoPreload: 'none', // 'metadata' not supported on tablets
8028 autoplay: false
8029 });
8030 }
8031 return settings;
8032 },
8033
8034 overrideMobileSettings: function(settings) {
8035 if (MHP1138.detector.isMobile()) {
8036 deepExtend(settings, {
8037 features: {
8038 ignorePreferences: true
8039 },
8040 videoPreload: 'none', // 'metadata' not supported on tablets
8041 autoplay: false
8042 });
8043 }
8044 return settings;
8045 },
8046
8047 overrideSafariSettings: function(settings) {
8048 //getting autoplay state, as safari requires preload metadata if auto play is on
8049 this.getStoredAutoplayState(settings);
8050 var regex = new RegExp(/Apple Computer/), //for chrome also isSafari returns true as chrome's useragent has word safari
8051 isSafari = browser.name == 'safari' && regex.test(navigator.vendor);
8052
8053 if (browser.type == 'desktop' && isSafari && this.autoplay) {
8054 deepExtend(settings, {
8055 videoPreload: 'none',
8056 features: {
8057 showAutoplayOption: false
8058 }
8059 })
8060
8061 //Added because of Safari 11 autoplay block
8062 this.setAutoplay(false);
8063 }
8064 return settings;
8065 },
8066
8067 supportDefaultOverlayTextAd: function(settings) {
8068 var textAd = settings.mainRoll.overlayTextAd;
8069 if (textAd && textAd.displayText.length) {
8070 __.extend(textAd, {
8071 label: textAd.displayText,
8072 time: textAd.showDelay,
8073 duration: textAd.displayDuration,
8074 bottom: '60px',
8075 fontScale: '3%',
8076 hCentered: true
8077 });
8078 settings.mainRoll.overlays.push(textAd);
8079 }
8080 return settings;
8081 },
8082
8083 // support for deprecated medias array
8084 supportDeprecatedSettings: function(settings) {
8085 if (!__.isEmpty(settings.medias)) {
8086 //removeIf(production)
8087 MHP1138.warn('You are using deprecated "medias" structure, upgrade your config to "mainRoll"');
8088 //endRemoveIf(production)
8089 }
8090
8091 return settings;
8092 },
8093
8094 // init quality state
8095 getStoredQuality: function() {
8096 if (this.settings.embeds.enabled) {
8097 return;
8098 }
8099
8100 var storedValue = store.get('player_quality');
8101 if (storedValue &&
8102 this.videoSources[storedValue.quality] &&
8103 this.videoSources[storedValue.quality].format !== 'upsell'
8104 ) {
8105 this.selectedResolution = storedValue.quality;
8106 }
8107 },
8108
8109 getStoredAutoplayState: function(settings) {
8110 var storedState = store.get('player_autoplay');
8111
8112 // override from player config
8113 if (settings.autoplay) {
8114 this.setAutoplay(true);
8115 }
8116
8117 //embed mode hardcoded settings
8118 if (settings.features.ignorePreferences) {
8119 if (!settings.autoplay) {
8120 this.setAutoplay(false);
8121 }
8122 } else if (storedState && !__.isUndefined(storedState.autoplay)) {
8123 this.setAutoplay(storedState.autoplay);
8124 }
8125 },
8126
8127 getStoredMotionRate: function() {
8128 var settings = this.settings,
8129 storedState = store.get('player_motionRate');
8130
8131 if (storedState && !__.isUndefined(storedState.motionRate)) {
8132 this.setMotionRate(storedState.motionRate);
8133 } else {
8134 this.setMotionRate(1);
8135 }
8136 },
8137
8138 getStoredHotspotsState: function() {
8139 var settings = this.settings,
8140 storedState = store.get('player_hotspots');
8141
8142 this.hotspotsState = settings.features.showHotspots;
8143
8144 if (storedState && !__.isUndefined(storedState.hotspotsState)) { //embed mode hardcoded settings
8145 this.setHotspotsState(storedState.hotspotsState);
8146 }
8147
8148 fireEvent('onHotspotsStateChange', { hotspotsState: this.hotspotsState });
8149 },
8150
8151 getStoredVolume: function() {
8152 var settings = this.settings,
8153 storedVolume = store.get('player_volume');
8154
8155 if (!storedVolume || settings.features.ignorePreferences) {
8156 var startVolume = 100,
8157 startMute = false;
8158 } else if (storedVolume && !__.isUndefined(storedVolume.volume)) {
8159 var startVolume = storedVolume.volume,
8160 startMute = storedVolume.isMuted;
8161 }
8162
8163 //Set the video volume based on the start volume
8164 this.setVolume(startVolume);
8165 this.setMute(startMute);
8166 },
8167
8168 initContainer: function() {
8169 var container = document.getElementById(this.playerId);
8170 //removeIf(production)
8171 //check to be sure that a container was created for the player
8172 if (!container) {
8173 MHP1138.error('You need to create a container element for the player with ID "#'+ this.playerId +'".');
8174 return;
8175 }
8176 //endRemoveIf(production)
8177
8178 MHP1138.detector.generateClassList(container);
8179 __.addClass(container, 'container');
8180 // hide controls bar on player init, only centered play button shown and only on desktop
8181 // show controls on embed player init unless playback is started
8182 if (!this.settings.embeds.enabled) {
8183 __.addClass(container, 'hideControls');
8184 }
8185
8186 //add embedded class to the container
8187 if (this.settings.embeds.enabled) {
8188 __.addClass(container, 'embedded');
8189 }
8190
8191 //WARNING, ANY REFERENCE OR EVENTS BINDED ON THE PLAYER ELEMENTS BEFORE THIS LINE WILL BE DELETED!!!!!!
8192 //Where copying the skin markup to the current player
8193 var playerMarkup = MHP1138.skinsMarkup['markup'];
8194
8195 container.innerHTML = playerMarkup;
8196 this.playerContainerElement = container;
8197 },
8198
8199 initSkin: function() {
8200 this.skin.init(this, function() {
8201 //the callback
8202 });
8203 },
8204
8205 _appendUrlParams: function(url, params) {
8206 if (url.indexOf('?') == -1) {
8207 url = url + '?' + params.substring(1);
8208 } else {
8209 url += params;
8210 }
8211 return url;
8212 },
8213
8214 initSourceParams: function(source){
8215 var urlParams = '';
8216 if (source.params) {
8217 if (typeof source.params == 'string') {
8218 urlParams = '&' + source.params
8219 } else {
8220 each(source.params, function(value, key) {
8221 urlParams += '&' + key + '=' + value;
8222 })
8223 }
8224 }
8225
8226 return urlParams;
8227 },
8228
8229 initHlsPlayer: function(source) {
8230 var self = this,
8231 path = source.videoUrl,
8232 urlParams = '';
8233 if (!window.Hls || !Hls.isSupported()) {
8234 return;
8235 }
8236
8237 // load NEW source to existing hls player
8238 if (this.hlsPlayer) {
8239 this.hlsPlayer.loadSource(path);
8240 return;
8241 }
8242
8243 urlParams = this.initSourceParams(source);
8244
8245 this.hlsPlayer = new Hls(deepExtend({}, this.settings.hlsSettings, {
8246 fetchSetup: function(context, initParams) {
8247 // Always send cookies, even for cross-origin calls.
8248 //initParams.credentials = 'include';
8249 return new Request(self._appendUrlParams(context.url, urlParams), initParams);
8250 },
8251 xhrSetup: function(xhr, url) {
8252 //xhr.withCredentials = true; // do send cookies
8253 // hackery: overriding xhr.open request made before xhrSetup callback
8254 xhr.open('GET', self._appendUrlParams(url, urlParams), true);
8255 }
8256 }));
8257 this.hlsPlayer.attachMedia(this.playerElement);
8258 this.hlsPlayer.loadSource(path);
8259 // cache the HLS source value for later use
8260 this.hlsSource = source;
8261 this.bindHlsPlayerEvents(this.hlsPlayer);
8262 // set flag to change quality to manual value on CAN_PLAY event
8263 if (typeof source.quality == 'string') {
8264 this.hlsQuality = source.quality;
8265 }
8266
8267 // check for updates of the player container to re-set quality limit
8268 // window.addEventListener('resize', function() {
8269 // // hls video is playing AND was set to Auto quality
8270 // if (this.hlsSource && !this.hlsQuality) {
8271 // this.limitHlsQualityByPortal();
8272 // }
8273 // });
8274 },
8275
8276 bindHlsPlayerEvents: function(hls) {
8277 var self = this,
8278 skin = this.skin,
8279 settings = this.settings;
8280
8281 // hls.on(Hls.Events.MEDIA_ATTACHED, function () {
8282 // console.log("HLS: parser attached to the video tag");
8283 // });
8284
8285 hls.on(Hls.Events.MANIFEST_PARSED, function() {
8286 // deferred manual quality selection
8287 if (self.hlsQuality) {
8288 self.setHlsQuality(self.hlsQuality);
8289 } else {
8290 //self.limitHlsQualityByPortal();
8291 }
8292 });
8293
8294 hls.on(Hls.Events.LEVEL_SWITCHED,function(data1, data2) {
8295 fireEvent('onAdaptiveQualityChange', {quality:hls.levels[data2.level]});
8296 });
8297
8298 hls.on(Hls.Events.FRAG_CHANGED,function(data1, data2) {
8299 var chunkDetails = {
8300 'hlsChunkId' : data2.frag.sn,
8301 'hlsChunkSize' : data2.frag.loaded,
8302 'hlsChunkQuality' : data2.frag.level,
8303 'hlsChunkBandwidth' : self.hlsPlayer.streamController.fragLastKbps
8304 }
8305
8306 fireEvent('fragmentChanged', {chunkDetails:chunkDetails});
8307 //levels : 0-240, 1-380, 2-480, 3-720, 4-1080
8308 });
8309
8310 hls.on(Hls.Events.ERROR, function (event, data) {
8311 if (data.fatal) {
8312 switch (data.type) {
8313 case Hls.ErrorTypes.NETWORK_ERROR:
8314 // try to recover network error
8315 console.log("HLS: fatal network error encountered, try to recover");
8316 // hls.startLoad();
8317 skin.videoNotAvailable(l(settings.htmlSettings.videoErrorMessage));
8318 break;
8319 case Hls.ErrorTypes.MEDIA_ERROR:
8320 skin.videoNotAvailable(l(settings.htmlSettings.videoErrorMessage));
8321 console.log("HLS: fatal media error encountered, try to recover");
8322 //hls.recoverMediaError();
8323 break;
8324 default:
8325 // cannot recover
8326 self.destroyHlsPlayer();
8327 }
8328 }
8329 });
8330 },
8331
8332 setHlsQuality: function(quality) {
8333 if (!this.hlsSource) return;
8334 var hls = this.hlsPlayer,
8335 list = hls.levels;
8336
8337 each(list, function(el, index) {
8338 if (parseInt(quality) == el.height || parseInt(quality) == parseInt(el.name)) {
8339 hls.nextLevel = index;
8340 // hls.loadLevel = index;
8341 // hls.currentLevel = index;
8342 self.hlsQuality = quality;
8343 hls.autoLevelCapping = -1; // disable quality cap
8344 }
8345 });
8346 },
8347
8348 setHlsAutoQuality: function() {
8349 if (!this.hlsSource) return;
8350 var hls = this.hlsPlayer;
8351
8352 hls.nextLevel = -1;
8353 //hls.loadLevel = -1;
8354 //hls.currentLevel = -1;
8355 this.hlsQuality = false;
8356 //this.limitHlsQualityByPortal();
8357 },
8358
8359 limitHlsQualityByPortal: function() {
8360 if (!this.hlsPlayer) return;
8361 var hls = this.hlsPlayer,
8362 list = hls.levels,
8363 maxIndex = -1,
8364 playerHeight = this.playerContainerElement.clientHeight;
8365
8366 each(list, function(el, index) {
8367 var qHeight = Math.max(el.height, parseInt(el.name));
8368 // 120px is the margin delta to have a chance to set quality cap one step further than player height
8369 // '480p' for H360px player and so on
8370 if (index > maxIndex && qHeight <= playerHeight + 120) {
8371 maxIndex = index;
8372 }
8373 });
8374 hls.autoLevelCapping = maxIndex;
8375 },
8376
8377 destroyHlsPlayer: function() {
8378 this.hlsPlayer.destroy();
8379 this.hlsPlayer = false;
8380 this.hlsSource = false;
8381 },
8382
8383 initDashPlayer: function(source) {
8384 if (!window.dashjs) return false;
8385
8386 var self = this,
8387 path = source.videoUrl,
8388 urlParams = '';
8389
8390 if (this.dashPlayer) {
8391 // restart existing player
8392 this.dashPlayer.pause();
8393 this.dashPlayer.attachSource(path);
8394 return;
8395 }
8396
8397 urlParams = this.initSourceParams(source);
8398
8399 this.dashPlayer = dashjs.MediaPlayer().create();
8400 this.dashPlayer.initialize(this.playerElement, null, false);
8401 this.dashPlayer.extend('RequestModifier', function() {
8402 return {
8403 modifyRequestURL: function(url) {
8404 return self._appendUrlParams(url, urlParams);
8405 }
8406 };
8407 },
8408 true
8409 );
8410
8411 this.applyDashSettings(this.dashPlayer);
8412 this.dashPlayer.attachSource(path);
8413 this.dashSource = source;
8414 this.bindDashPlayerEvents(this.dashPlayer);
8415 // set flag to change quality to manual value on CAN_PLAY event
8416 if (typeof source.quality == 'string') {
8417 this.dashQuality = source.quality;
8418 }
8419 },
8420
8421 applyDashSettings: function(dash) {
8422 var debug = dash.getDebug();
8423 debug.setLogToBrowserConsole(false);
8424
8425 dash.setFastSwitchEnabled(true); // REPLACE loaded chunks instead of adding new to the end of buffered part
8426 // // initial value, do not buffer anything
8427 dash.setStableBufferTime(30); // default is 12sec
8428 dash.setBufferTimeAtTopQuality(120); // default is 30sec
8429 // dash.setBandwidthSafetyFactor(0.1);
8430 dash.setBufferTimeAtTopQualityLongForm(120); // default is 60sec
8431 // dash.enableLastBitrateCaching(true, 7 * 24 * 60 * 60 * 100) // 7 days
8432 // dash.enableLastMediaSettingsCaching(true, 7 * 24 * 60 * 60 * 100) // 7 days
8433 // limit the representation used based on the size of the playback area
8434 //dash.setLimitBitrateByPortal(true);
8435 // count retina pixels too
8436 //dash.setUsePixelRatioInLimitBitrateByPortal(true);
8437 },
8438
8439 bindDashPlayerEvents: function(dash) {
8440 var self = this,
8441 skin = this.skin,
8442 settings = this.settings,
8443 timer;
8444
8445 function resizeDashPortal() {
8446 if (dash.getLimitBitrateByPortal()) {
8447 clearTimeout(timer);
8448 timer = setTimeout(function() {
8449 dash.updatePortalSize();
8450 }, 1000);
8451 }
8452 }
8453
8454 // update portal size if window / player dimensions changed
8455 subscribeToEvent('collapsePlayer', resizeDashPortal);
8456 subscribeToEvent('expandPlayer', resizeDashPortal);
8457 window.addEventListener('resize', resizeDashPortal);
8458
8459 // dash.on(dashjs.MediaPlayer.events.MANIFEST_LOADED, function (e) {
8460 // console.log('DASH: MANIFEST_LOADED', e);
8461 // });
8462
8463 var firstTimeReady = true;
8464 dash.on(dashjs.MediaPlayer.events.CAN_PLAY, function (e) {
8465 // console.log('DASH: CAN_PLAY', e);
8466
8467 // CAN_PLAY fires every time player prebuffers stream after lag
8468 // We need only the very first action
8469 if (firstTimeReady) {
8470 // deferred manual quality selection
8471 if (self.dashQuality) {
8472 self.setDashQuality(self.dashQuality);
8473 }
8474 if (self.autoplay) {
8475 self.playerElement.play();
8476 }
8477 firstTimeReady = false;
8478 }
8479 });
8480
8481 dash.on(dashjs.MediaPlayer.events.ERROR, function (e) {
8482 console.log('DASH: fatal media error encountered', e);
8483 skin.videoNotAvailable(l(settings.htmlSettings.videoErrorMessage));
8484 });
8485
8486 // dash.on(dashjs.MediaPlayer.events.QUALITY_CHANGE_REQUESTED, function (e) {
8487 // if (e.mediaType == 'video') {
8488 // console.log('DASH: QUALITY_CHANGE_REQUESTED', e);
8489 // }
8490 // });
8491
8492 dash.on(dashjs.MediaPlayer.events.QUALITY_CHANGE_RENDERED, function (e) {
8493 var qualitiesList = self.dashPlayer.getActiveStream().getBitrateListFor(e.mediaType),
8494 currentQuality = qualitiesList[e.newQuality];
8495
8496 fireEvent('onAdaptiveQualityChange', {quality:currentQuality});
8497 });
8498
8499 // dash.on(dashjs.MediaPlayer.events.PERIOD_SWITCH_COMPLETED, function (e) {
8500 // console.log('DASH: PERIOD_SWITCH_COMPLETED');
8501 // });
8502
8503 // dash.on(dashjs.MediaPlayer.events.STREAM_INITIALIZED, function (e) {
8504 // console.log('DASH: STREAM_INITIALIZED');
8505 // });
8506
8507 var firstTimePlaying = true;
8508 dash.on(dashjs.MediaPlayer.events.PLAYBACK_PLAYING, function(e) {
8509 //console.log('DASH: PLAYBACK_PLAYING');
8510 if (firstTimePlaying) {
8511 // allow up to 6sec to buffer
8512 //dash.setStableBufferTime(6);
8513 firstTimePlaying = false;
8514 }
8515 });
8516
8517 // dash.on(dashjs.MediaPlayer.events.PLAYBACK_PAUSED, function(e) {
8518 // console.log('DASH: PLAYBACK_PAUSED');
8519 // });
8520
8521 // dash.on(dashjs.MediaPlayer.events.PLAYBACK_SEEKING, function(e) {
8522 // console.log('DASH: PLAYBACK_SEEKING');
8523 // });
8524
8525 // dash.on(dashjs.MediaPlayer.events.PLAYBACK_SEEKED, function(e) {
8526 // console.log('DASH: PLAYBACK_SEEKED');
8527 // });
8528
8529 // dash.on(dashjs.MediaPlayer.events.PLAYBACK_ENDED, function(e) {
8530 // console.log('DASH: PLAYBACK_ENDED');
8531 // });
8532
8533 dash.on(dashjs.MediaPlayer.events.FRAGMENT_LOADING_COMPLETED, function(e, data) {
8534 if(e.request.mediaType === 'video') {
8535 var requestDuration = e.request.requestEndDate.valueOf()-e.request.requestStartDate.valueOf();
8536
8537 var chunkDetails = {
8538 'hlsChunkId' : e.request.index,
8539 'hlsChunkSize' : e.request.bytesLoaded,
8540 'hlsChunkQuality' : e.request.quality,
8541 'hlsChunkDownloadTime' : requestDuration,
8542 'hlsChunkBandwidth' : (e.request.bytesLoaded * 8 / requestDuration).toFixed(2)
8543 }
8544
8545 fireEvent('fragmentChanged', {chunkDetails:chunkDetails});
8546 }
8547 });
8548 },
8549
8550 setDashQuality: function(quality) {
8551 if (!this.dashSource) return;
8552 var self = this,
8553 dash = this.dashPlayer,
8554 list = dash.getBitrateInfoListFor('video');
8555
8556 //console.log('list:', list, 'buffered: ', dash.getBufferLength()/*, dash.setBufferToKeep(0)*/);
8557 //dash.setBufferToKeep(0.5); // 0.5sec // doesnt seems to be working
8558 each(list, function(el) {
8559 if (parseInt(quality) == el.height) {
8560 //dash.setLimitBitrateByPortal(false);
8561 dash.setAutoSwitchQualityFor('video', false);
8562 dash.setQualityFor('video', el.qualityIndex);
8563 self.dashQuality = quality;
8564 }
8565 });
8566 },
8567
8568 setDashAutoQuality: function() {
8569 if (!this.dashSource) return;
8570 var dash = this.dashPlayer;
8571 // return to default value
8572 //dash.setLimitBitrateByPortal(true);
8573 dash.setAutoSwitchQualityFor('video', true);
8574 this.dashQuality = false;
8575 },
8576
8577 destroyDashPlayer: function() {
8578 // no need to actually destroy DASH player
8579 // in a way we do so for HLS
8580
8581 // But we have to reset DASH player (2.4.1) this way
8582 // Setting wrong/empty source brings "dash media error" to console.
8583 // This hack allows regular .mp4 playback ONLY after that
8584 // in any other case, DASH lib blocks it
8585 this.dashPlayer.pause();
8586 this.dashPlayer.attachSource('#');
8587 this.dashSource = false;
8588 },
8589
8590 initPreRoll: function() {
8591 var roll = this.initAdsRoll('pre');
8592 this.preRoll = roll;
8593 },
8594
8595 showPreRoll: function() {
8596 this.isPreRollActive = true;
8597 this.showAdsRoll(this.preRoll);
8598 },
8599
8600 initPauseRoll: function() {
8601 var roll = this.initAdsRoll('pause');
8602 this.pauseRoll = roll;
8603 },
8604
8605 showPauseRoll: function() {
8606 this.isPauseRollActive = true;
8607 this.showAdsRoll(this.pauseRoll);
8608 },
8609
8610 skipPauseRoll: function() {
8611 this.isPauseRollActive = false;
8612 this.hideStaticRoll();
8613 this.enableOptions();
8614 // if (!this.pauseRoll.repeat) {
8615 // this.pauseRoll.enabled = false;
8616 // }
8617 },
8618
8619 showMainRoll: function() {
8620 var mainRoll = this.mainRoll,
8621 settings = this.settings;
8622
8623 // no reason to set poster if it will be replaced by ad in a moment
8624 // no reason to set poster if the seek bar will be moved
8625 if (!parseInt(settings.startOffset) && !this.autoplay ||
8626 settings.startOffset && !MHP1138.detector.isDesktop() ||
8627 this.preRoll.enabled && !this.autoplay
8628 ) {
8629 this.setPoster(mainRoll.poster);
8630 }
8631
8632 // Set the video duration if it's given as a parameter,
8633 // so it's not shown as empty before the metadata are loaded.
8634 if (mainRoll.duration > 0) {
8635 this.updateDuration(mainRoll.duration);
8636 this.setActionTags(mainRoll.actionTags);
8637 this.setOverlays(mainRoll.overlays);
8638 }
8639 },
8640
8641 incrementRollCounter: function() {
8642 if(this.prerollCookie) {
8643 store.set('player_preroll', this.prerollCookie);
8644 }
8645 },
8646
8647 initAdsRoll: function(prefix) {
8648 var self = this,
8649 timestamp = new Date().getTime(),
8650 settings = this.settings,
8651 roll = settings[prefix+'Roll'],
8652 defaultRollObject = this.settings.defaultRollObject,
8653 campaigns = [],
8654 campaignCandidates = [],
8655 candidates = [],
8656 cookie = store.get('player_'+prefix+'roll') || {
8657 views: 0,
8658 time: {}
8659 };
8660
8661 if (__.isEmpty(roll)){
8662 return false;
8663 }
8664
8665 //TFE-718 fix for users who has old localStorage data structure
8666 if(!__.isObject(cookie.time)){
8667 cookie.time = {};
8668 }
8669
8670 // Increase counter of views
8671 cookie.views += 1;
8672
8673 if(!__.isArray(roll)) {
8674 roll = [roll];
8675 }
8676
8677 this.campaignCandidates = roll;
8678
8679 each(roll, function(candidate, index) {
8680 candidate.onNth +=1;
8681
8682 //removeIf(production)
8683 if (typeof candidate.repeat !== 'undefined'){
8684 //Parameter will be removed in version 2.5.0
8685 MHP1138.warn('You are using deleted "repeat" parameter in roll section, please upgrade your config.');
8686 }
8687 //endRemoveIf(production)
8688
8689 // apply default settings to each roll candidate
8690 candidate = deepExtend({}, defaultRollObject, candidate);
8691
8692 // resetTime is the number of seconds (default is 24Hrs) to reset the display of ads roll
8693 var resetTime = candidate.forgetUserAfter * 1000;
8694
8695 // create empty array for campaign candidates
8696 if(__.isUndefined(campaignCandidates[candidate.campaign])){
8697 campaignCandidates[candidate.campaign] = [];
8698 }
8699
8700 // first time, cookie doesn't exist yet
8701 if(__.isUndefined(cookie.time[candidate.campaign])){
8702 cookie.time[candidate.campaign] = 0;
8703 }
8704
8705 // check if forgetUserAfter time for this campaign didn't pass yet
8706 if ((timestamp - cookie.time[candidate.campaign] > resetTime)) {
8707 campaignCandidates[candidate.campaign].push(candidate);
8708 }
8709 });
8710
8711 campaigns = __.keys(campaignCandidates);
8712 each(campaigns, function(campaign, index) {
8713 // looking for roll candidates as array
8714 var cn = self.filterRollCandidates(campaignCandidates[campaign], cookie.views);
8715 if(cn.length){
8716 cn = cn[__.random(cn.length - 1)]
8717 candidates.push(cn);
8718 }
8719 });
8720
8721 // if all candidates failed the test
8722 if (!candidates.length) {
8723 store.set('player_' + prefix + 'roll', cookie);
8724 return false;
8725 }
8726
8727 // or choose random one from array
8728 // roll set to object! no more arrays at this point
8729 roll = candidates[__.random(candidates.length - 1)];
8730 if(!this.settings.isVr) {
8731 roll.enabled = true;
8732 }
8733
8734 if (!this.checkRollPath(roll)) return false;
8735
8736 if (!__.isUndefined(roll.mediaDefinition)){
8737 if (roll.mediaDefinition.length) {
8738 roll.videoUrl = roll.mediaDefinition[0].videoUrl;
8739 }
8740 }
8741
8742 // legacy properties for 4play
8743 if (isPath(roll.imageUrl)) {
8744 roll.type = 'static';
8745 roll.static = true;
8746 roll.variant = 'image';
8747 delete roll.trackUrl; // disable tracking for static rolls
8748 } else if (isPath(roll.videoUrl)) {
8749 roll.type = 'video';
8750 roll.video = true;
8751 }
8752 roll.timing = prefix + 'roll';
8753
8754 // special treatment for pauseRolls
8755 //
8756 // no 'playing' functionality for static images while on pause
8757 // but show them on every pause event
8758 if (prefix == 'pause') {
8759 if (isPath(roll.imageUrl)) {
8760 roll.skipDelay = 0;
8761 roll.enabled = true;
8762
8763 // block video ads on pause
8764 // if accidentally set in settings
8765 } else if (isPath(roll.videoUrl)) {
8766 roll.enabled = false;
8767 }
8768 } else {
8769 // staticRolls on pre or post should be disabled
8770 if (isPath(roll.imageUrl)) {
8771 roll.enabled = false;
8772 }
8773 }
8774
8775 if (roll.enabled) {
8776 if (roll.skippable) {
8777 if (!roll.skipMessage) {
8778 roll.skipMessage = l(settings.htmlSettings.skipMessage)
8779 }
8780 if (!roll.skipDelayMessage) {
8781 roll.skipDelayMessage = l(settings.htmlSettings.skipDelayMessage);
8782 }
8783 }
8784
8785 var defaultTrackUrl = settings.htmlSettings.adsTrackUrl;
8786
8787 if (!roll.trackUrl) {
8788 roll.trackUrl = [defaultTrackUrl];
8789 } else if(__.isArray(roll.trackUrl)){
8790 roll.trackUrl.push(defaultTrackUrl);
8791 } else if(__.isString(roll.trackUrl)) {
8792 // do not fire track callback twice if urls are the same
8793 if (roll.trackUrl != defaultTrackUrl) {
8794 roll.trackUrl = [roll.trackUrl, defaultTrackUrl];
8795 } else {
8796 roll.trackUrl = [defaultTrackUrl];
8797 }
8798 }
8799
8800 // update stored timestamp to current time of displayed ad
8801 // views counter stays the same
8802 cookie.time[roll.campaign] = timestamp;
8803 this.prerollCookie = cookie;
8804 }
8805
8806 return roll;
8807 },
8808
8809 showAdsRoll: function(roll) {
8810 var self = this;
8811
8812 // video source
8813 if (isPath(roll.videoUrl)) {
8814 self.showAdsRollUI(roll);
8815 self.firePreRollEvent = true;
8816 // callback would never happen if there is no videoPreload = 'metadata'
8817 this.setSource(roll, function() {
8818 if (self.isPreRollActive) {
8819 fireEvent('showPreRoll');
8820 }
8821 });
8822
8823 // static image
8824 } else if (isPath(roll.imageUrl)) {
8825 this.playStaticRoll(roll);
8826 }
8827 },
8828
8829 // TODO: move it to skin
8830 showAdsRollUI: function(roll) {
8831 this.setOverlays([]);
8832 this.showRollAdsMessage();
8833 if (roll.skippable) {
8834 // right after switching from mainRoll vid and currentTime has prev value
8835 this.currentTime = 0;
8836 this.initRollSkipButton(roll);
8837 this.showRollSkipButton();
8838 }
8839 },
8840
8841 // TODO: move it to skin
8842 hideAdsRollUI: function() {
8843 var skin = this.skin;
8844
8845 this.hideRollAdsMessage();
8846 this.hideRollSkipButton();
8847 this.enableOptions();
8848
8849 if (skin.seekBarController) {
8850 skin.seekBarController.move(0);
8851 } else {
8852 // legacy code support
8853 skin.seekBarRemoveAnimation();
8854 skin.updateSeekBarPosition(0);
8855 setTimeout(function() {
8856 skin.seekBarAddAnimation();
8857 }, 100);
8858 }
8859 },
8860
8861 filterRollCandidates: function(roll, rollViewCount) {
8862 var candidates = [];
8863 each(roll, function(candidate) {
8864 // support legacy naming
8865 if (__.isUndefined(candidate.onNth) &&
8866 __.isNumber(candidate.on_nth)
8867 ) {
8868 candidate.onNth = candidate.on_nth;
8869 }
8870 //we filter the invalid onNth with modulus
8871 if (rollViewCount % candidate.onNth) return false;
8872
8873 candidates.push(candidate);
8874 });
8875 return candidates;
8876 },
8877
8878 checkRollPath: function(roll) {
8879 if (!isPath(roll.videoUrl) &&
8880 !isPath(roll.imageUrl)
8881 ) {
8882 return false;
8883 } else {
8884 return true;
8885 }
8886 },
8887
8888 initRollSkipButton: function(roll) {
8889 if (!this.rollSkipButton) {
8890 this.createRollSkipButton();
8891 }
8892 this.updateRollSkipButton(roll);
8893 },
8894
8895 createRollSkipButton: function() {
8896 var self = this;
8897 this.rollSkipButton = __.xest('#' + this.playerId + ' .mhp1138_preRollSkipButton div');
8898 if (!this.rollSkipButton) return;
8899 // rollSkipButton is a label inside actual button
8900 var eventType = MHP1138.detector.isDesktop() ? 'click' : 'touchstart';
8901 this.rollSkipButton.parentNode.addEventListener(eventType, function () {
8902 if (self.rollTimeLeft <= 0) {
8903 var roll = self.adsRoll();
8904 if (roll) {
8905 self.adsRollTracking(roll, 'skip');
8906 }
8907 self.deferredPreRoll = false;
8908 //button need to hidden immediately after 1st user's skip
8909 //if not then it takes time to hide untill call back is received
8910 //and user can skip multiple times
8911 self.hideRollSkipButton();
8912 self.setSource(
8913 self.getCurrentQualitySource(),
8914 self.changeVideoSourceCallback.bind(self)
8915 );
8916 }
8917 });
8918 },
8919
8920 updateRollSkipButton: function(roll) {
8921 if (roll.skippable) {
8922 this.rollTimeLeft = Math.floor(roll.skipDelay - Math.floor(this.currentTime));
8923
8924 if (!this.rollSkipButton) return;
8925 if (this.rollTimeLeft > 0) {
8926 this.rollSkipButton.innerHTML = roll.skipDelayMessage.replace('%', this.rollTimeLeft).replace('(s)', (this.rollTimeLeft>1?'s':''));
8927 } else {
8928 this.rollSkipButton.innerHTML = roll.skipMessage;
8929 }
8930 }
8931 },
8932
8933 showRollSkipButton: function() {
8934 if (this.rollSkipButton) {
8935 this.rollSkipButton.parentNode.style.display = 'block';
8936 }
8937 },
8938
8939 hideRollSkipButton: function() {
8940 if (this.rollSkipButton) {
8941 this.rollSkipButton.parentNode.style.display = 'none';
8942 }
8943 },
8944
8945 showRollAdsMessage: function() {
8946 __.addClass(this.playerContainerElement, 'preRollRunning');
8947 },
8948
8949 hideRollAdsMessage: function() {
8950 __.removeClass(this.playerContainerElement, 'preRollRunning');
8951 },
8952
8953 getCurrentQualitySource: function() {
8954 return this.videoSources[this.selectedResolution];
8955 },
8956
8957 bindPlayerEvents: function() {
8958 var self = this,
8959 settings = this.settings,
8960 isOldBrowser = (browser.version || MHP1138.iOSversion) <= 9,
8961 isOldSafari = isOldBrowser && (browser.name === 'safari' || isIosTablet);
8962
8963 //TOTAL DURATION
8964 this.playerElement.ondurationchange = function(e) {
8965 // skip duration update on preroll metadata load,
8966 // to create effect of main video will be played on button click
8967 if (self.deferredPreRoll) {
8968 self.adDuration = this.duration;
8969 return;
8970 }
8971 // 'this' is referring to player video tag
8972 if (self.duration != this.duration) {
8973 self.updateDuration(this.duration);
8974 if (!self.adsRoll()) {
8975 var mainRoll = settings.mainRoll;
8976 self.setActionTags(mainRoll.actionTags);
8977 self.setOverlays(mainRoll.overlays);
8978 }
8979 }
8980 };
8981
8982 //CURRENT TIME
8983 this.playerElement.ontimeupdate = function() {
8984 var time;
8985 if (self.chromecast.active) {
8986 time = self.chromecast.remotePlayer.currentTime;
8987 } else {
8988 time = this.currentTime;
8989 }
8990 fireEvent('onBuffer', { buffered: this.buffered, duration: this.duration });
8991
8992 if (!self.updatingSource && !self.seeking) {
8993 self.updateCurrentTime(time);
8994 }
8995
8996 var roll = self.adsRoll();
8997 if (roll) {
8998 self.updateRollSkipButton(roll);
8999 }
9000 };
9001
9002 //BUFFERING PROGRESSION
9003 this.playerElement.onprogress = function(e) {
9004 fireEvent('onBuffer', { buffered: this.buffered, duration: this.duration });
9005 };
9006
9007 //STOP TO BUFFER
9008 this.playerElement.onwaiting = function(){
9009 fireEvent('onWaiting');
9010 self.playing = false;
9011 };
9012
9013 this.playerElement.onpause = function() {
9014 if (!self.seeking) {
9015 fireEvent('onPause');
9016 }
9017 self.playing = false;
9018 }
9019
9020 this.playerElement.onplaying = function() {
9021 self.videoEnded = false;
9022 if (!self.videoStarted) {
9023 self.videoStarted = true;
9024 self.showVideoTag();
9025 }
9026
9027 if (self.deferredPreRoll) {
9028 self.updateDuration(self.adDuration);
9029 }
9030
9031 if (!self.initialSeek && !self.seeking && !self.seekToEnd) {
9032 fireEvent('onPlay', { playAfterSeek: self.playAfterSeek });
9033 fireEvent('hideRoll');
9034 }
9035
9036 self.updatingSource = false;
9037 self.playing = true;
9038 };
9039
9040 this.playerElement.onseeked = function() {
9041 // 'this' is referring to self.playerElement, no need to use player object
9042 if (this.paused) {
9043 // player was paused before source change,
9044 // need to fire pause event for newly loaded source
9045 if (self.updatingSource || self.initialSeek || self.seeking) {
9046 self.playing = false;
9047 if (!self.seekToEnd) {
9048 fireEvent('onPause');
9049 }
9050 }
9051 self.updatingSource = false;
9052 }
9053 self.seeking = false;
9054
9055 if (self.deferredSeek) {
9056 self.seek(self.deferredSeek.offset, self.deferredSeek.playAfter);
9057 self.deferredSeek = false;
9058 } else if (self.deferredPause && !this.paused) {
9059 self.playing = true;
9060 self.deferredPause = false;
9061 self.pause();
9062 // playerElement wouldnt fire onpause event because the player pauses vid before every seek call
9063 // need to fire it manually
9064 fireEvent('onPause');
9065 } else if (self.playAfterSeek) {
9066 self.play();
9067 fireEvent('onPlay', { playAfterSeek: self.playAfterSeek });
9068 }
9069
9070 if (self.initialSeek) {
9071 self.initialSeek = false;
9072 //IOS fires onseeked after play when seeked initially before playback
9073 if (!this.videoStarted && isIos) {
9074 self.play();
9075 fireEvent('onPlay', { playAfterSeek: self.playAfterSeek });
9076 }
9077 self.showVideoTag();
9078 }
9079 };
9080
9081 this.playerElement.oncanplay = function() {
9082 if (!self.videoStarted) {
9083 self.videoReady(this.src)
9084 }
9085 };
9086
9087 //ON END
9088 this.playerElement.onended = function() {
9089 var roll = self.adsRoll();
9090 if (self.isPreRollActive) {
9091 self.deferredPreRoll = false;
9092
9093 self.setSource(
9094 self.getCurrentQualitySource(),
9095 self.changeVideoSourceCallback.bind(self)
9096 );
9097 self.adsRollTracking(roll, 'finish');
9098
9099 return;
9100 }
9101
9102 self.videoEnded = true;
9103 self.playing = false;
9104
9105 //Stop the counter because user reached the end of the video and havent seen 60 secs
9106 self.stopViewedCounter();
9107
9108 self.fireEndEvent();
9109 fireEvent('showPostRoll');
9110 self.seekToEnd = false;
9111 };
9112
9113 if (settings.videoPreload == 'none' ) {
9114 this.videoReady(this.playerElement.src);
9115 }
9116
9117 if(isOldSafari) {
9118 this.playerElement.addEventListener('seeked', function(){
9119 self.playerElement.onseeked();
9120 });
9121 }
9122
9123 this.playerCreated = true;
9124 },
9125
9126
9127 skinNotReady: function() {
9128 //removeIf(production)
9129 MHP1138.warn('Wait for "onSkinReady" event');
9130 //endRemoveIf(production)
9131 },
9132
9133 playerNotReady: function() {
9134 //removeIf(production)
9135 MHP1138.warn('Wait for "onReady" event');
9136 //endRemoveIf(production)
9137 },
9138
9139 fireVolumeChangeEvent: function() {
9140 if (!this.settings.features.ignorePreferences) {
9141 this.saveVolumeToCookie(this.volume, this.muted);
9142 }
9143
9144 fireEvent('onVolumeChange', {
9145 volume : this.volume,
9146 muted : this.muted
9147 });
9148 },
9149
9150 saveVolumeToCookie: function(newVolume, isMuted) {
9151 store.set('player_volume', {
9152 volume : newVolume,
9153 isMuted : isMuted
9154 });
9155 },
9156
9157 saveQualityToCookie: function(newQuality) {
9158 store.set('player_quality', { quality: newQuality });
9159 },
9160
9161 saveAutoplay: function(autoplay) {
9162 this.setAutoplay(autoplay);
9163 store.set('player_autoplay', { autoplay: autoplay });
9164 },
9165
9166 saveSlowMotionRate: function(motionRate) {
9167 store.set('player_motionRate', { motionRate: motionRate });
9168 },
9169
9170 saveHotspotsState: function(hotspotsState) {
9171 store.set('player_hotspots', { hotspotsState: hotspotsState });
9172 },
9173
9174 replaceTrackUrlMasks: function(roll, action, url) {
9175 var appid = roll.appId,
9176 site = encodeURIComponent(roll.clickUrl),
9177 siteName = encodeURIComponent(roll.siteName ? roll.siteName : 'undefined'),
9178 adTitle = encodeURIComponent(roll.title ? roll.title : 'undefined'),
9179 campaign = encodeURIComponent(roll.campaignName),
9180 platform = MHP1138.detector.isDesktop() ? 'PC' : 'Mobile';
9181
9182 var link = url.replace('%APPID%', appid)
9183 .replace('%ACTION%', action)
9184 .replace('%SITE%', site)
9185 .replace('%CAMPAIGN%', campaign)
9186 .replace('%PLAYER%', this.playerType)
9187 .replace('%PLATFORM%', platform)
9188 .replace('%ADTITLE%', adTitle);
9189
9190 if (siteName.length > 0) {
9191 link = link.replace('%SITENAME%', siteName);
9192 }
9193
9194 return link;
9195 },
9196
9197 // TODO: implement google masking standard
9198
9199 replaceVASTTrackUrlMasks: function(roll, action, url) {
9200 var link = url;
9201 return link;
9202 },
9203
9204 adsRollTracking: function (roll, action) {
9205 var url = roll.trackUrl;
9206
9207 if (roll.vastParser) {
9208 if (action == 'play' &&
9209 roll.impressionUrl
9210 ) {
9211 url = roll.impressionUrl;
9212 } else if (action == 'click' &&
9213 roll.clickTrackUrl
9214 ) {
9215 url = roll.clickTrackUrl;
9216 }
9217 } else {
9218 url = roll.trackUrl;
9219 }
9220
9221 for (var i = 0, len = url.length; i < len; i++) {
9222 var link = '';
9223 if (isPath(url[i])) {
9224 link = this.replaceTrackUrlMasks(roll, action, url[i]);
9225 if (roll.vastParser) {
9226 link = this.replaceVASTTrackUrlMasks(roll, action, link);
9227 } else {
9228 // DEPRECATED
9229 // Do not call remote track urls except for the 'play' events
9230 // ('first impression' in VAST terminology)
9231 // but do so for our own tracker (etahub)
9232 //
9233 // VAST urls however should be called for ANY event
9234 if (action != 'play' &&
9235 link.indexOf('etahub.com') == -1
9236 ) {
9237 continue;
9238 }
9239 }
9240
9241 __.ajaxLoader(link);
9242 }
9243 }
9244 },
9245
9246 setQuality: function(resolution, callback) {
9247 var sources = this.videoSources,
9248 source = sources[resolution],
9249 src = source.videoUrl || '',
9250 format = source.format;
9251
9252 this.selectedResolution = resolution;
9253 this.selectedFormat = format;
9254
9255 fireEvent('onQualityChange', {
9256 src: src,
9257 resolution: resolution,
9258 format: format
9259 });
9260
9261 fireEvent('hideRoll');
9262
9263 // stop all activity and event handlers while changing video!
9264 if (this.vrPlayer) {
9265 this.vrPlayer.stop();
9266 }
9267
9268 if (this.seeking) {
9269 this.qualityChanged = true;
9270 }
9271
9272 if (format == 'dash') {
9273 if (resolution == 'dash') { // Auto
9274 this.setDashAutoQuality();
9275 } else {
9276 this.setDashQuality(resolution);
9277 }
9278 } else if (format == 'hls') {
9279 if (resolution == 'hls') { // Auto
9280 this.setHlsAutoQuality();
9281 } else { // integer value
9282 this.setHlsQuality(resolution);
9283 }
9284 } else {
9285 this.setSource(source);
9286 }
9287
9288 this.saveQualityToCookie(resolution);
9289
9290 if (format == 'dash' || format == 'hls') {
9291 if (this.videoStarted) {
9292 if (this.playing) {
9293 fireEvent('onPlay');
9294 } else {
9295 fireEvent('onPause');
9296 }
9297 } else {
9298 fireEvent('onVideoReady')
9299 }
9300 }
9301
9302 if (__.isFunction(callback)) {
9303 callback();
9304 }
9305 },
9306
9307 setSource: function(source, callback) {
9308 var self = this,
9309 path = source.videoUrl,
9310 fileExtention = __.extractFileExtention(path),
9311 previousTime = this.playerElement.currentTime,
9312 wasPlaying = this.playing;
9313
9314 this.updatingSource = true;
9315
9316 var loadedCallback = function(e) {
9317 // special case: stream change was started in videoEnded state, we need to restore it
9318 if (self.videoEnded) {
9319 fireEvent('onEnd');
9320 fireEvent('showPostRoll');
9321 } else {
9322 self.videoReady(path);
9323 var roll = self.adsRoll();
9324 // seek to the same position after changing source (if its not 0)
9325 if (!roll && previousTime && self.updatingSource) {
9326 self.seek(previousTime, wasPlaying);
9327 }
9328 }
9329
9330 if (__.isFunction(callback)) {
9331 callback();
9332 }
9333 };
9334
9335 if (this.isPreRollActive && this.firePreRollEvent){
9336 this.firePreRollEvent = false;
9337 if (__.isFunction(callback)) {
9338 callback();
9339 }
9340 }
9341
9342 if (!this.videoStarted) {
9343 this.videoReady(path);
9344 } else {
9345 this.playerElement.oncanplay = loadedCallback
9346 }
9347
9348 // init custom media stream players on quality change
9349
9350 if (source.format != 'hls' && this.hlsPlayer) {
9351 this.destroyHlsPlayer();
9352 }
9353
9354 if (source.format != 'dash' && this.dashPlayer && this.dashSource) {
9355 this.destroyDashPlayer();
9356 }
9357
9358 if (source.format == 'hls') {
9359 this.initHlsPlayer(source);
9360 return;
9361 }
9362
9363 if (source.format == 'dash') {
9364 this.initDashPlayer(source);
9365 return;
9366 }
9367
9368 // update preload value to "auto"
9369 // no need to use .play() or .load()
9370 // mobiles only
9371 this.playerElement.src = path;
9372
9373 if (this.isPreRollActive || this.videoStarted) {
9374 this.playerElement.preload = 'auto';
9375
9376 //ios unable preload and requires play()
9377 if (isIos) {
9378 this.playerElement.load();
9379 }
9380 }
9381
9382 if (this.chromecast.active && this.chromecast.castSession) {
9383 this.chromecast.playerState = 'LOADING';
9384 this.chromecast.setupRemotePlayer(this.chromecast.castSession);
9385 this.chromecast.seek(this.currentTime, true);
9386 }
9387
9388 //playback rate need to be reset if source is changed
9389 //for ios need to set playback after load() else it'll be set to default value(1)
9390 if (!__.isUndefined(this.slowMotion) && !this.isPreRollActive) {
9391 this.playerElement.playbackRate = this.slowMotion;
9392 }
9393
9394 if (this.seeking && this.qualityChanged){
9395 this.seeking = false;
9396 this.qualityChanged = false;
9397 if (!this.initialSeek) {
9398 wasPlaying = true;
9399 this.playerElement.play();
9400 }
9401 }
9402 },
9403
9404 changeVideoSourceCallback: function() {
9405 // caching value to start main video playback immediatelly after preRoll
9406 var preRollState = this.isPreRollActive;
9407 this.hideAdsRollUI();
9408 // active flags should be reset BEFORE main video playback
9409 this.isPreRollActive = false;
9410 this.preRoll.enabled = false;
9411 if (this.chromecast.castAvailable) {
9412 this.chromecast.initializeCastPlayer();
9413 }
9414
9415 // preroll was playing before
9416 if (preRollState) {
9417 this.setActionTags(this.mainRoll.actionTags);
9418 this.playing = false;
9419 if(!__.isUndefined(this.slowMotion)) {
9420 this.playerElement.playbackRate = this.slowMotion;
9421 }
9422 if (parseInt(this.settings.startOffset) > 0) {
9423 // seek and play
9424 this.seek(parseInt(this.settings.startOffset), true);
9425 } else {
9426 // just play
9427 this.play();
9428 }
9429 }
9430 },
9431
9432 setAutoplay: function(state) {
9433 this.autoplay = state;
9434 fireEvent('onAutoplayChange', { autoplay: state });
9435 },
9436
9437 setMotionRate: function(rate) {
9438 this.slowMotion = rate;
9439
9440 if(!__.isUndefined(rate)) {
9441 this.playerElement.playbackRate = rate;
9442 }
9443 this.saveSlowMotionRate(rate);
9444
9445 fireEvent('onSlowMotionChange', { motionRate: rate });
9446 },
9447
9448 setHotspotsState: function(state) {
9449 this.hotspotsState = state;
9450
9451 // apply but do not store new values in embedded mode
9452 if (!this.settings.embeds.enabled) {
9453 this.saveHotspotsState(state);
9454 }
9455 fireEvent('onHotspotsStateChange', { hotspotsState: state });
9456 },
9457
9458 togglePlayPause: function() {
9459 if (!this.playing) {
9460 this.play();
9461 } else {
9462 this.pause();
9463 }
9464 },
9465
9466 toggleCinemaMode: function() {
9467 fireEvent((this.cinemaMode?'collapsePlayer':'expandPlayer'));
9468 this.cinemaMode = !this.cinemaMode;
9469 },
9470
9471 //CURRENT TIME
9472 updateCurrentTime: function(currentTime) {
9473 // doublecheck
9474 // IE sometimes fires really weird numbers!
9475 if (__.isNaN(currentTime)) currentTime = 0;
9476 if (currentTime < 0) currentTime = 0;
9477 if (currentTime > this.duration) currentTime = this.duration;
9478
9479 this.currentTime = currentTime;
9480 fireEvent('onTimeChange', { time: currentTime, duration: this.duration });
9481
9482 var timeLeft = Math.floor(this.duration) - Math.floor(currentTime);
9483 //onPlaylistCountdown
9484 if (timeLeft < 4) {
9485 if ((!this.onPlaylistCountdownLastTimeFired && timeLeft) ||
9486 timeLeft == (this.onPlaylistCountdownLastTimeFired - 1)
9487 ) {
9488 this.onPlaylistCountdownLastTimeFired = timeLeft;
9489 fireEvent('onPlaylistCountdown', { count: timeLeft });
9490 }
9491 } else if (this.onPlaylistCountdownLastTimeFired > 0) {
9492 this.onPlaylistCountdownLastTimeFired = 0;
9493 }
9494 },
9495
9496 //TOTAL DURATION
9497 updateDuration: function(duration) {
9498 // doublecheck
9499 // IE sometimes fires really weird numbers!
9500 if (__.isNaN(duration)) duration = 0;
9501
9502 this.duration = parseFloat(duration);
9503 fireEvent('onDurationChange', { duration: duration });
9504 },
9505
9506 fireEndEvent: function() {
9507 fireEvent('onEnd');
9508 },
9509
9510 fireUpsellEvent: function() {
9511 fireEvent('onQualityUpsell');
9512 },
9513
9514 fireShareEvent: function() {
9515 fireEvent('onShare');
9516 },
9517
9518 addUTM: function(url, medium, campaign){
9519 url += (( url.indexOf('?') < 0 ) ? '?' : '&') +'utm_source='+ this.settings.referrerUrl +'&utm_medium='+ medium +'&utm_campaign='+ campaign;
9520 return url;
9521 },
9522
9523 addCurrentTimeToUrl: function(url) {
9524 url = url.replace(/[?&]t=\d+/, ''); // delete previous timestamp if exists
9525 url += (( url.indexOf('?') < 0 ) ? '?' : '&') +'t='+ Math.floor(this.currentTime || 0);
9526 return url;
9527 },
9528
9529 // just a quick macro
9530 openRedirectWindow: function(url, targetSelf) {
9531 fireEvent('onRedirect');
9532 var target = targetSelf ? '_self' : '_blank';
9533 window.open(url, target);
9534 },
9535
9536 //API
9537
9538 play: function() {
9539 if (!this.playerCreated) { this.playerNotReady(); return false; }
9540
9541 if (this.deferredPreRoll) {
9542 this.showPreRoll();
9543 this.deferredPreRoll = false;
9544 }
9545
9546 var roll = this.adsRoll();
9547 if (roll) {
9548 if (this.isPauseRollActive) {
9549 // pauseRoll skipped by pressing player's play button
9550 // hide static pause roll and restore normal player state
9551 if (!roll.paused) {
9552 this.adsRollTracking(roll, 'skip');
9553 roll.paused = true;
9554 }
9555 this.skipPauseRoll();
9556 } else {
9557 // pre or post roll started
9558
9559 // do not send play event twice if advertising was paused
9560 if (!roll.played) {
9561 this.incrementRollCounter();
9562 this.adsRollTracking(roll, 'play');
9563 this.disableOptions();
9564 this.showRollSkipButton();
9565 roll.played = true;
9566 }
9567 }
9568 }
9569
9570 if (this.chromecast.active) {
9571 this.chromecast.play();
9572 } else {
9573 if (!this.videoStarted && this.deferredStartSeek) {
9574 this.seek(this.settings.startOffset, true);
9575 this.playerElement.play();
9576 } else {
9577 this.playerElement.play();
9578 }
9579 }
9580 this.playing = true;
9581 if (roll === false) {
9582 this.startViewedCounter();
9583 }
9584 },
9585
9586 pause: function() {
9587 var settings = this.settings;
9588 if (!this.playerCreated) { this.playerNotReady(); return false; }
9589
9590 if (this.playing) {
9591 if (this.chromecast.active) {
9592 this.chromecast.pause();
9593 } else {
9594 this.playerElement.pause();
9595 }
9596
9597 if (!this.updatingSource) {
9598 // do nothing on pre/post rolls pausing
9599 if (this.isPreRollActive) {
9600 return;
9601 }
9602
9603 if (this.pauseRoll.enabled) {
9604 this.disableOptions();
9605 this.showPauseRoll();
9606 } else if (!settings.embeds.enabled) {
9607 fireEvent('showPauseRoll');
9608 }
9609 }
9610 } else {
9611 // deferred pause
9612 this.deferredPause = true;
9613 this.playAfterSeek = false;
9614 this.deferredSeek = false;
9615 }
9616 this.stopViewedCounter(this.currentTime);
9617 },
9618
9619 seek: function(offset, playAfter) {
9620 offset = parseFloat(offset);
9621 if (__.isNaN(offset)) return false;
9622
9623 if (!this.playerCreated) {
9624 this.playerNotReady();
9625 return false;
9626 }
9627
9628 // you shall not pass the counter!
9629 if (this.adsRoll() && !this.isPauseRollActive) { // (except static pause rolls)
9630 return false;
9631 }
9632
9633 // chromecast fires onSeek event by itself
9634 // no deferredSeek support for remote device, just make it simple
9635 if (this.chromecast.active) {
9636 this.chromecast.seek(offset, playAfter);
9637 return;
9638 }
9639
9640 if (this.seeking) {
9641 this.deferredSeek = {
9642 offset: offset,
9643 playAfter: playAfter
9644 };
9645 return false;
9646 }
9647 // could be used only once, reset the flag if manual seek was done
9648 this.deferredStartSeek = false;
9649
9650 var self = this,
9651 previousTime = this.playerElement.currentTime;
9652
9653 // IE fix for seekbar X-coords incorrect rounding
9654 if (offset > this.duration) {
9655 offset = this.duration;
9656 }
9657
9658 // special case of seeking to the end of video
9659 // do seek to at least 1 frame before the actual video end,
9660 // to reach it (and trigger 'onended' event) in playing state
9661 if (offset == this.duration) {
9662 offset -= 0.05; // 1sec / 24fps = 0.041666
9663 }
9664
9665 // initial player state, no video loaded or played yet
9666 // do deferred seek right AFTER canplay event
9667 // DO NOT fire onSeek event to skin
9668 if (this.playerElement.readyState == 0) {
9669 // statically named function to use removeEventListener later
9670 function playOnReady(e) {
9671 this.removeEventListener('canplay', playOnReady);
9672 // aditional flag for first-time seek without immediate play
9673 // to prevent normal event firing
9674 self.initialSeek = true;
9675
9676 //fireEvent('onVideoReady');
9677
9678 /* MAGIC */
9679
9680 // put on pause to get 'seeked' event in IE
9681 // (they wouldnt fire it if player is playing something at this moment)
9682 if(MHP1138.detector.isIe()){
9683 this.pause();
9684 }
9685 // set currentTime from startOffset property
9686 this.currentTime = offset;
9687 self.seeking = true;
9688 self.playAfterSeek = playAfter;
9689
9690 // "seek to the end" has its special treatment (and callbacks chain)
9691 // because when you just load video and do like vid.currentTime = vid.duration
9692 // IEs dont fire "onended" event. Videos should be finished by actual playing to get the event,
9693 // so each seek of this type looks like
9694 // vid.currentTime = vid.duration - 0.05sec;
9695 // vid.play();
9696 if (this.duration - offset < 0.06) {
9697 self.seekToEnd = true;
9698 }
9699 }
9700 // play() will be fired at the end of this method
9701 // and the real seek will be done right after the vid will start ('canplay' event)
9702 this.playerElement.addEventListener('canplay', playOnReady);
9703
9704 //IE bug TFE-460. Playback starts after switching the quality
9705 if (!this.dashSource && // DASH player fires error at this moment, source isnt ready yet
9706 typeof browser.name != 'undefined' &&
9707 browser.name != 'ie' &&
9708 playAfter
9709 ) {
9710 // manually play the video to get canplay event and process seek!
9711 this.playerElement.play();
9712 }
9713 setTimeout(function() {
9714 if (playAfter) {
9715 self.showVideoTag();
9716 }
9717 }, 200); // time to show/animate seekPreview before hiding poster
9718 return;
9719 }
9720
9721 // HACKERY
9722 // IE doesnt fire 'onplaying' event after 'seeked' if seek happend in play state
9723 // need to manually put player on pause
9724 // (WARN: do not use this.pause() as it does much more than just pausing the player)
9725 this.playerElement.pause();
9726 this.playing = false;
9727
9728 this.playerElement.currentTime = offset;
9729 this.seeking = true;
9730 this.playAfterSeek = playAfter;
9731
9732 this.stopViewedCounter(previousTime);
9733
9734 fireEvent('onSeek', {
9735 from: previousTime,
9736 to: offset,
9737 duration: this.duration
9738 });
9739 fireEvent('hideRoll');
9740 },
9741
9742 videoReady: function(path) {
9743 if (path != this.sourceUrl) {
9744 fireEvent('onVideoReady');
9745 }
9746 this.sourceUrl = path;
9747 },
9748
9749 showVideoTag: function() {
9750 // TODO: remove direct control
9751 this.playerElement.style.visibility = 'visible';
9752 this.playerPoster.style.display = 'none';
9753 },
9754
9755 playStaticRoll: function(roll) {
9756 // create image container before first use
9757 if (!this.staticRollContainer) {
9758 this.createStaticRollContainer();
9759 }
9760
9761 if (!roll.played) {
9762 this.adsRollTracking(roll, 'play');
9763 this.staticRollContainer.style.backgroundImage = 'url(' + roll.imageUrl + ')';
9764 roll.played = true;
9765 }
9766
9767 this.showStaticRoll();
9768 },
9769
9770 createStaticRollContainer: function() {
9771 // WARN: could create bug in multi-player environment
9772 this.staticRollContainer = satisfy('.mhp1138_staticRoll.mhp1138_hidden')[0];
9773 this.videoWrapper.appendChild(this.staticRollContainer);
9774 },
9775
9776 showStaticRoll: function() {
9777 __.removeClass(this.staticRollContainer, 'hidden');
9778 },
9779
9780 hideStaticRoll: function() {
9781 __.addClass(this.staticRollContainer, 'hidden');
9782 },
9783
9784 isVideoStarted: function(){
9785 return this.videoStarted;
9786 },
9787
9788 isPlaying: function() {
9789 return this.isReady ? !this.playerElement.paused : false;
9790 },
9791
9792 isReady: function() {
9793 return this.isReady;
9794 },
9795
9796 adsRoll: function() {
9797 if (this.isPreRollActive) {
9798 return this.preRoll;
9799 } else if (this.isPauseRollActive) {
9800 return this.pauseRoll;
9801 } else {
9802 return false;
9803 }
9804 },
9805
9806 getVolume: function(){
9807 return this.volume;
9808 },
9809
9810 setVolume: function(volumeLevel){
9811 if (!__.isNaN(volumeLevel)) {
9812 if (volumeLevel > 100) volumeLevel = 100;
9813 if (volumeLevel < 0) volumeLevel = 0;
9814
9815 this.volume = volumeLevel;
9816 this.playerElement.volume = volumeLevel / 100;
9817 this.fireVolumeChangeEvent();
9818 }
9819 },
9820
9821 setMute: function(state) {
9822 if (__.isBoolean(state) && state != this.muted) {
9823 this.playerElement.muted = state;
9824 this.muted = state;
9825 this.fireVolumeChangeEvent();
9826 }
9827 },
9828
9829 getCurrentTime: function() {
9830 return Math.round(this.playerElement.currentTime); // do we really need it rounded to seconds?
9831 },
9832
9833 setPoster: function(url) {
9834 this.posterUrl = url;
9835 // transparent gif image
9836 //var videoPosterImage = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
9837 if (isPath(url)) {
9838 this.playerPoster.setAttribute('style', "background-image: url('" + url + "')");
9839 //this.playerElement.setAttribute('poster', videoPosterImage);
9840 } else {
9841 //this.playerElement.setAttribute('poster', '');
9842 this.showVideoTag();
9843 }
9844 },
9845
9846 setActionTags: function(actionTags) {
9847 this.actionTags = actionTags;
9848 // TODO: remove direct calls but switch to firing internal event to skin
9849 this.skin.deleteActionTags();
9850 this.skin.createActionTags();
9851 },
9852
9853 enableOptions: function() {
9854 this.skin.enableOptions();
9855 },
9856
9857 disableOptions: function() {
9858 this.skin.disableOptions();
9859 },
9860
9861 startViewedCounter: function(){
9862 var self = this,
9863 link = this.settings.viewedRequestURL || '',
9864 timeout = this.settings.viewedRequestTimeout;
9865 this.viewedTimeout = this.viewedTimeout || null;
9866
9867 if(!link) return;
9868
9869 this.viewingStart = this.playerElement.currentTime;
9870 if(this.viewedSeconds < timeout){
9871 this.viewedTimeout = setTimeout(function(){
9872 self.viewedSeconds = timeout;
9873 //poke the server after "this.settings.viewedRequestTimeout" sec of viewing
9874 __.ajaxLoader(link);
9875 }, timeout*1000-this.viewedSeconds*1000);
9876 }
9877 },
9878
9879 stopViewedCounter: function(currentTime){
9880 if(this.viewedTimeout){
9881 currentTime = currentTime || this.playerElement.currentTime;
9882 this.viewingStart = this.viewingStart || 0;
9883 this.viewedSeconds += Math.floor(currentTime) - Math.floor(this.viewingStart);
9884 clearTimeout(this.viewedTimeout);
9885 }
9886 },
9887
9888 //remove the player
9889 destroy: function(callback) {
9890 // Reset video tag event handlers to interrupt lazy networking and so on
9891 // Browsers could spend up to several seconds on actual videoElement destroy
9892 // Sometimes we are getting events from the World of the Dead
9893 this.playerElement.ondurationchange = function() {};
9894 this.playerElement.ontimeupdate = function() {};
9895 this.playerElement.onprogress = function() {};
9896 this.playerElement.onwaiting = function() {};
9897 this.playerElement.onpause = function() {};
9898 this.playerElement.onplaying = function() {};
9899 this.playerElement.onseeked = function() {};
9900 this.playerElement.oncanplay = function() {};
9901 this.playerElement.onended = function() {};
9902
9903 this.playerContainerElement.parentNode.removeChild(this.playerContainerElement);
9904 callback();
9905 }
9906 };
9907}