Files
sm-bm-plugin/public/assets/CastReceiverView-C3JQv3Bs.js

2 lines
17 KiB
JavaScript

import"./engine-DDeQk6Ow.js";import{c as Ee}from"./presentations-CkEsPiie.js";import{_ as Se}from"./DeckViewer.vue_vue_type_style_index_0_lang-BxQIjO4L.js";import{A as Q,d as Me,o as Re,aH as _e,aN as ie,c as W,s as Ce,f as ne,b as Y,F as Te,r as J,aO as se,n as P,aM as Ae,aP as Le,Z as Ne}from"./index-CcttGF2j.js";import{C as re,f as ue,a as Pe,c as De,r as Ie,b as Fe}from"./log-Xlt5jeld.js";import{b as Oe,R as je}from"./remote-aOKX75Mt.js";const Be=/^U\+(0-FF|100-2BA)\b/i;function We(e){return e.status==="unloaded"&&Be.test(e.unicodeRange.trim())}async function ze(e){const o=[...e].filter(We);return await Promise.allSettled(o.map(r=>r.load())),o.length}async function Ue(e,o){const r=e.filter(l=>l.classList.contains("on"));try{for(const l of e){for(const c of e)c.classList.toggle("on",c===l);l.offsetHeight,await o()}}finally{for(const l of e)l.classList.toggle("on",r.includes(l))}return e.length}async function $e(e,o,r=50){const l=Date.now()+o;for(;;){if(e())return!0;if(Date.now()>=l)return!1;await new Promise(c=>setTimeout(c,r))}}function fe(){return{raf:e=>requestAnimationFrame(()=>e()),cancelRaf:e=>cancelAnimationFrame(e),setTimeout:(e,o)=>window.setTimeout(e,o),clearTimeout:e=>window.clearTimeout(e),now:()=>performance.now()}}async function qe(e,o=fe()){return(await de(Number.POSITIVE_INFINITY,e,o)).frames}function de(e,o,r=fe()){return new Promise(l=>{const c=r.now();let h=0,g=0,f=0,y=!1;const d=s=>{y||(y=!0,r.cancelRaf(g),r.clearTimeout(f),l({frames:h,ms:Math.round(r.now()-c),ok:s}))},v=()=>{y||(h++,h>=e?d(!0):g=r.raf(v))};f=r.setTimeout(()=>d(!1),o),g=r.raf(v)})}const Ge="https://www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js",ce="bm-caf",me=["READY","SENDER_CONNECTED","SENDER_DISCONNECTED","SHUTDOWN","VISIBILITY_CHANGED","STANDBY_CHANGED","ERROR"],He=540*1e3,Ke="/icons/icon-96.png";function z(){const o=globalThis.cast?.framework;return o&&typeof o.CastReceiverContext?.getInstance=="function"?o:null}function Ve(){return z()!==null}function xe(e=1e4){return z()?Promise.resolve(!0):new Promise(o=>{let r=document.getElementById(ce);r||(r=document.createElement("script"),r.id=ce,r.src=Ge,document.head.appendChild(r));const l=r;let c=!1;const h=v=>{c||(c=!0,window.clearInterval(y),window.clearTimeout(d),l.removeEventListener("load",g),l.removeEventListener("error",f),o(v))},g=()=>h(z()!==null),f=()=>h(!1);l.addEventListener("load",g),l.addEventListener("error",f);const y=window.setInterval(()=>{z()&&h(!0)},50),d=window.setTimeout(()=>h(z()!==null),e)})}function Ye(e,o,r){const l=e.messages,c=o.getPlayerManager?.();if(!l||!c)return()=>r("keep-awake-failed",{error:"no player manager"});const h=document.createElement("cast-media-player");h.style.display="none",document.body.append(h);const g=()=>{for(const v of document.body.querySelectorAll("touch-controls"))v.style.display!=="none"&&(v.style.display="none")};new MutationObserver(g).observe(document.body,{childList:!0,subtree:!0});const f=e.events?.EventType?.ERROR;f!==void 0&&c.addEventListener&&c.addEventListener(f,v=>{const s=v.error;r("keep-awake-error",{detailedErrorCode:v.detailedErrorCode??null,reason:v.reason??null,error:s?.message??(s?String(s):null)})});let y=0;const d=()=>{try{const v=new l.LoadRequestData;v.autoplay=!0;const s=new l.MediaInformation;s.contentId=new URL(Ke,location.origin).href,s.contentType="image/png",s.streamType=l.StreamType.NONE;const E=new l.GenericMediaMetadata;E.title="BM · prezentacja",s.metadata=E,v.media=s,v.requestId=0,y++,Promise.resolve(c.load(v)).then(()=>r("keep-awake",{count:y}),b=>{const k=b;r("keep-awake-failed",{count:y,error:String(k?.type??b),reason:k?.reason??null,detailedErrorCode:k?.detailedErrorCode??null})})}catch(v){r("keep-awake-failed",{count:y,error:v instanceof Error?v.message:String(v)})}};return()=>{d(),window.setInterval(d,He)}}function Je(e){const o=z();if(!o)throw new Error("cast: the receiver SDK is not loaded");const r=o.CastReceiverContext.getInstance(),l=()=>{try{return r.getSenders().length}catch{return 0}},c=new o.CastReceiverOptions;c.customNamespaces={[re]:o.system.MessageType.JSON},c.disableIdleTimeout=!0,c.maxInactivity=3600,c.statusText=e.statusText;for(const f of me){const y=o.system.EventType[f];y!==void 0&&r.addEventListener(y,d=>{e.onEvent(f,{reason:d?.reason,senderId:d?.senderId,isVisible:d?.isVisible,isStandby:d?.isStandby,senders:l()})})}r.addCustomMessageListener(re,f=>e.onMessage(f?.data,f?.senderId));const h=Ye(o,r,e.onEvent),g=o.system.EventType.READY;if(g!==void 0){let f=!1;r.addEventListener(g,()=>{f||(f=!0,h())})}return r.start(c),{send(f,y){if(!ue(f))return e.onEvent("send-dropped",{type:f.type}),!1;try{return r.sendCustomMessage(re,y,f),!0}catch(d){return e.onEvent("send-failed",{type:f.type,error:d instanceof Error?d.message:String(d)}),!1}},senders:l,setStatusText(f){try{r.setApplicationState(f)}catch{}},deviceCapabilities(){try{return r.getDeviceCapabilities?.()??null}catch{return null}}}}const Ze=2e3,Qe=5e3,Xe=/data-deck-image="([^"]+)"/g;function et(e){const o=new Set,r=c=>{if(c)for(const h of c.matchAll(Xe))o.add(h[1])},l=c=>{r(c.body_html),r(c.comment_html),r(c.sources_html),c.special&&l(c.special)};for(const c of e.slides??[])l(c);return[...o]}function H(e){return e instanceof Q?e.status:0}function Z(e){return e instanceof Q?`${e.status} ${e.message}`:e instanceof Error?e.message:String(e)}function tt(e){const o=e.now??(()=>Date.now());let r=null,l=null,c=null,h=null,g="waiting",f="off",y="",d=0,v=-1/0,s=!1,E,b,k=-1/0,S=null,U=!1,T=[],D="",$=0,K=0,V=0;function A(){const t=e.view.current();return{type:"status",phase:g,ws:f,number:t?.number??0,special:t?.special??!1,title:y}}function I(){return E??b}function x(){const t=I();t!==void 0&&e.send(A(),t)}function F(){const t=A();e.onStatus?.(t);const n=I();n!==void 0&&e.send(t,n)}function q(t){g!==t&&(g=t,e.log("phase",t),F())}function O(t){if(f===t)return;const n=f;n==="connected"&&t==="connecting"&&V++,f=t,e.log("ws",`${n} -> ${t}`),F()}function j(t){const n=o();n-v<Ze||(v=n,e.log("ticket","need-ticket",{why:t}),e.send({type:"need-ticket"}))}async function B(t,n,a=r){if(!a)throw new Q(401,"no ticket");try{return await n(a)}catch(m){throw H(m)===401&&a===r&&j(t),m}}async function G(t){const n=o();try{const a=await B(t,e.api.realtime);return e.log("token",`${t} ok`,{kind:t,outcome:"ok",ms:Math.round(o()-n)}),a}catch(a){const m=H(a),w=m===401||m===403||m===404?"refused":"failed";throw e.log("token",`${t} ${w}`,{kind:t,outcome:w,status:m,ms:Math.round(o()-n)}),a}}function X(){e.realtime.setTokenSource({connection:async()=>(await G("connection")).token,subscription:async t=>{const n=await G("subscription");if(n.channel!==t)throw e.log("token","subscription channel mismatch"),new Q(403,"cast: channel mismatch");return n.channel_token}})}function i(t=T){for(const n of t)e.revokeURL(n);t===T&&(T=[])}async function u(t,n,a){const m={};return await Promise.all(et(t).map(async w=>{try{const N=await B("image",R=>e.api.image(R,w),n);if(a!==d||s)return;const C=e.objectURL(N);T.push(C),m[w]=C}catch(N){e.log("image","image skipped",{name:w,status:H(N)})}})),m}function p(){h?.close(),h=null}function M(t){const n=()=>t===d&&!s;return{onPublication(a){if(!n())return;const m=Oe(a);if(!m||m.event!==je)return;const w=m.payload;if(w.tab!==l){K++,e.log("foreign","state from another tab",{tab:w.tab});return}$++,e.view.show(w.number,w.special,w.panel==="notes"||w.panel==="srcs"?w.panel:null),e.log("state","applied",{number:w.number,special:w.special})},onSubscribed(){n()&&(e.log("ws","subscribed"),g==="ready"&&F())},onConnection(a){n()&&O(a)},onDenied(a){n()&&(e.log("ws","subscription denied",{code:a}),a===401&&j("subscription denied"))},onUnavailable(){n()&&(O("off"),j("realtime unavailable"))}}}async function _(t,n){const a=await e.realtime.openChannel(n,M(t));if(t!==d||s){a.close();return}h=a}async function L(t,n){const a=++d,m=r,w=o();p(),e.realtime.disconnect(),c=null,D="",q("loading");const N=T;T=[];let C;try{if(C=n??await B("deck",e.api.deck,m),a!==d||s)return;y=C.title??"";const R=o(),oe=await u(C,m??"",a);if(a!==d||s)return;const ae=o();if(await e.view.load(C,oe),a!==d||s)return;D=JSON.stringify(C),e.log("perf","deck up",{fetchMs:Math.round(R-w),imagesMs:Math.round(ae-R),images:Object.keys(oe).length,loadMs:Math.round(o()-ae),totalMs:Math.round(o()-w),slides:C.slides?.length??0})}catch(R){if(a!==d||s)return;e.log("error","deck load failed",{error:Z(R)}),q("error");return}finally{i(N)}try{X();const R=t??await B("realtime",e.api.realtime,m);if(a!==d||s)return;c=R.channel,await _(a,R.channel)}catch(R){if(a!==d||s)return;e.log("error","channel join failed",{error:Z(R)}),O("off")}a!==d||s||q("ready")}async function ee(){if(!c)return;const t=d;p(),e.realtime.disconnect();try{await _(t,c)}catch(n){e.log("error","channel reopen failed",{error:Z(n)})}}async function te(t,n,a){if(!r){r=t,l=n,b=a,e.log("ticket","first hello",{tab:n}),await L(),r===t&&g==="ready"&&(E=a);return}if(t===r){if(l!==n&&e.log("tab","casting tab switched",{tab:n}),l=n,E=a,g==="error"||g==="ready"&&!h){await L();return}e.send(A(),a);return}let m;try{m=await e.api.realtime(t)}catch(w){e.log("ticket","refused",{status:H(w)}),e.send({...A(),title:""},a);return}if(!s){if(r=t,l=n,E=a,b=a,v=-1/0,c&&m.channel===c&&g==="ready"){let w=null;try{w=await e.api.deck(t)}catch(N){e.log("ticket","deck check failed",{status:H(N)})}if(s)return;if(w&&JSON.stringify(w)!==D){e.log("ticket","deck changed",{tab:n}),await L(m,w);return}if(e.log("ticket","swapped",{tab:n}),await ee(),s)return;e.send(A(),a);return}e.log("ticket","new deck",{tab:n}),await L(m)}}function we(t){const n=e.report?.()??{summary:null,device:null,events:[],previousRun:[]},a=De(JSON.stringify(Ie(n)));e.log("log","sending",{parts:a.length,senderId:t});for(const m of a){if(!ue(m)){e.log("log","part dropped",{part:m.part});continue}e.send(m,t)}}function ge(t){const n=e.view.current();e.send({type:"position",number:n?.number??0,special:n?.special??!1},t)}async function pe(t,n){if(s)return;const a=Pe(t);if(!a){e.log("foreign","unknown message",{senderId:n});return}if(e.log("rx",a.type,{senderId:n}),a.type==="where"){ge(n);return}if(a.type==="log"){if(n===void 0||n!==I()){e.log("foreign","log request refused",{senderId:n});return}we(n);return}const m=E!==void 0&&n===E||a.ticket===r;if(!m&&E!==void 0){if(o()<k){e.log("foreign","hello throttled",{senderId:n});return}k=o()+Qe}await ve(a.ticket,a.tab,n,m)}function ve(t,n,a,m){return new Promise(w=>{if(S){if(S.trusted&&!m){e.log("foreign","hello dropped behind a trusted one",{senderId:a}),w();return}e.log("rx","hello superseded",{senderId:S.senderId}),S.settle()}S={ticket:t,tab:n,senderId:a,trusted:m,settle:w},U||he()})}async function he(){U=!0;try{for(;S&&!s;){const t=S;S=null;try{await te(t.ticket,t.tab,t.senderId)}catch(n){e.log("error","hello failed",{error:Z(n)})}finally{t.settle()}}}finally{U=!1,S?.settle(),S=null}}function ye(t){t!==void 0&&t===b&&(b=void 0),!(t===void 0||t!==E)&&(E=void 0,e.log("rx","pinned sender left",{senderId:t}))}function ke(){s=!0,d++,p(),e.realtime.setTokenSource(null),i()}function be(){return{ws:f,applied:$,foreign:K,reconnects:V}}return{handle:pe,senderLeft:ye,status:A,announce:x,stats:be,close:ke}}const nt={key:1,class:"cast-screen cast-cover",role:"status"},rt={key:2,class:"cast-screen"},ot={key:0,class:"cast-hint"},at={key:3,class:"cast-screen"},it={key:4,class:"cast-screen"},st=6e4,le=1e3,wt=Me({__name:"CastReceiverView",setup(e){const o=J("boot"),r=se(null),l=se({}),c=J("pending"),h=J(null),g=J(!1);let f=null,y=null,d=0;const v=new Set(me),s=Fe("bm.cast.log"),E=Date.now();let b={};function k(i,u,p){s.note(i,u,p),i==="error"&&s.persist()}function S(){const i=performance.memory;return i?Math.round(i.usedJSHeapSize/1048576):null}function U(){const i=navigator;return{ua:navigator.userAgent,screen:`${window.screen.width}x${window.screen.height}`,viewport:`${window.innerWidth}x${window.innerHeight}`,dpr:window.devicePixelRatio,cores:navigator.hardwareConcurrency,memoryGB:i.deviceMemory??null}}function T(i,u){if(!v.has(i)){k(i.startsWith("keep-awake")?"awake":"send",i,u),i.startsWith("keep-awake-")&&s.persist();return}i==="READY"&&f?(b={...b,capabilities:f.deviceCapabilities()},k("caf",i,{...u,capabilities:b.capabilities})):k("caf",i,u),i==="SENDER_DISCONNECTED"&&typeof u?.senderId=="string"&&y?.senderLeft(u.senderId),s.persist()}function D(){return"serviceWorker"in navigator&&navigator.serviceWorker.controller!==null}function $(){return{screen:o.value,covered:g.value,coverInDom:document.querySelector(".cast-cover")!==null,visibility:document.visibilityState,focus:document.hasFocus(),sw:D()}}async function K(){const i=await qe(le),u=y?.stats();k("beat","heartbeat",{uptimeMin:+((Date.now()-E)/6e4).toFixed(1),ws:u?.ws??"off",applied:u?.applied??0,foreign:u?.foreign??0,reconnects:u?.reconnects??0,heapMB:S(),frames:i,frameSampleMs:le,...$()}),s.persist(),y?.announce()}async function V(){const i=await de(3,3e3);k("paint",i.ok?"frames after the cover":"no frames after the cover",{...i,...$()}),s.persist()}async function A(){if(!("serviceWorker"in navigator))return;const i=navigator.serviceWorker;try{const u=await i.getRegistrations(),p=i.controller!==null;if(u.length===0&&!p)return;const M=await Promise.all(u.map(_=>_.unregister().catch(()=>!1)));k("boot","service worker unregistered",{controlled:p,scopes:u.map(_=>_.scope),unregistered:M.filter(Boolean).length})}catch(u){k("boot","service worker check failed",String(u))}s.persist()}function I(i){k("error","window error",{message:String(i.message),source:i.filename,line:i.lineno})}function x(i){const u=i.reason instanceof Error?i.reason.message:String(i.reason);k("error","unhandled rejection",{reason:u})}function F(){k("boot","pagehide"),s.persist()}function q(i){return new Promise(u=>window.setTimeout(u,i))}function O(){return new Promise(i=>requestAnimationFrame(()=>i()))}function j(){return h.value?.sections()??[]}async function B(i,u){g.value=!0;const p=performance.now();try{r.value=i,l.value=u,c.value="ready",o.value="deck",await Ne(),await $e(()=>j().some(te=>te.classList.contains("on")),2e4)||k("error","the first slide did not show in 20 s"),await document.fonts.ready,await q(50);const M=performance.now(),_=await ze(document.fonts),L=performance.now(),ee=await Ue(j(),O);await O(),k("perf","warm-up",{stageMs:Math.round(M-p),faces:_,warmMs:Math.round(L-M),sections:ee,prerenderMs:Math.round(performance.now()-L),totalMs:Math.round(performance.now()-p)})}finally{g.value=!1,V()}}let G=null;function X(i){i.phase!==G&&(G=i.phase,i.phase==="loading"?g.value=!0:i.phase==="error"?(g.value=!1,o.value="error"):i.phase==="ready"&&r.value&&(g.value=!1,o.value="deck"))}return Re(async()=>{b=U();const i=s.previous[s.previous.length-1];if(k("boot","receiver loaded",{...b,cafAtBoot:Ve(),sw:D(),previousRunEvents:s.previous.length,lastPrevious:i??null}),s.persist(),A(),window.addEventListener("error",I),window.addEventListener("unhandledrejection",x),window.addEventListener("pagehide",F),d=window.setInterval(()=>{K()},st),document.documentElement.classList.add("deck-public"),!document.querySelector('meta[data-deck-public="1"]')){const p=document.createElement("meta");p.name="robots",p.content="noindex",p.dataset.deckPublic="1",document.head.appendChild(p)}if(!await xe()){o.value="unsupported",k("boot","no CAF SDK");return}o.value="waiting",y=tt({api:Ee,realtime:{setTokenSource:Le,openChannel:Ae,disconnect:ie},view:{load:B,show:(p,M,_)=>{h.value?.showSlide(p,M,_)},current:()=>h.value?.current()??null},send:(p,M)=>{f?.send(p,M)},log:k,objectURL:p=>URL.createObjectURL(p),revokeURL:p=>URL.revokeObjectURL(p),onStatus:X,report:()=>({summary:s.summary(),device:b,events:s.events,previousRun:s.previous})});const u=y;try{f=Je({statusText:"BM · prezentacja",onMessage:(p,M)=>{u.handle(p,M)},onEvent:T}),k("caf","started")}catch(p){k("error","receiver start failed",String(p)),o.value="unsupported"}}),_e(()=>{window.clearInterval(d),window.removeEventListener("error",I),window.removeEventListener("unhandledrejection",x),window.removeEventListener("pagehide",F),s.persist(),y?.close(),ie(),document.documentElement.classList.remove("deck-public"),document.querySelector('meta[data-deck-public="1"]')?.remove()}),(i,u)=>(P(),W(Te,null,[r.value?(P(),Ce(Se,{key:0,ref_key:"viewer",ref:h,phase:c.value,deck:r.value,error:"",mode:"public","no-toolbar":"","extra-css":r.value.css,theme:r.value.theme,images:l.value},null,8,["phase","deck","extra-css","theme","images"])):ne("",!0),g.value?(P(),W("div",nt,[...u[0]||(u[0]=[Y("p",null,"Przygotowuję slajdy…",-1)])])):o.value==="boot"||o.value==="waiting"?(P(),W("div",rt,[u[1]||(u[1]=Y("p",null,"BM · czekam na pilota…",-1)),o.value==="waiting"?(P(),W("p",ot,"Na telefonie otwórz pilota prezentacji i wybierz Wyświetl na TV.")):ne("",!0)])):o.value==="unsupported"?(P(),W("div",at,[...u[2]||(u[2]=[Y("p",null,"Ta strona działa tylko na urządzeniu Google Cast.",-1)])])):o.value==="error"?(P(),W("div",it,[...u[3]||(u[3]=[Y("p",null,"Nie mogę wczytać prezentacji. Połącz ponownie z telefonu.",-1)])])):ne("",!0)],64))}});export{wt as default};