HEX
Server: Apache/2.4.63 (Unix)
System: Linux TOMS-220NAS 4.4.302+ #86009 SMP Wed Nov 26 18:19:17 CST 2025 x86_64
User: flavio87 (1026)
PHP: 8.3.27
Disabled: NONE
Upload Files
File: //usr/syno/synoman/scripts/synowebrtc/synowebrtc.min.js
this.SYNO=this.SYNO||{},this.SYNO.WebRTC=function(){"use strict";function e(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function t(e){for(var t=[],n=0,s=0;s<e.length;s++){var i=e.charCodeAt(s);i<128?t[n++]=i:i<2048?(t[n++]=i>>6|192,t[n++]=63&i|128):55296==(64512&i)&&s+1<e.length&&56320==(64512&e.charCodeAt(s+1))?(i=65536+((1023&i)<<10)+(1023&e.charCodeAt(++s)),t[n++]=i>>18|240,t[n++]=i>>12&63|128,t[n++]=i>>6&63|128,t[n++]=63&i|128):(t[n++]=i>>12|224,t[n++]=i>>6&63|128,t[n++]=63&i|128)}return t}function n(e){for(var t,n,s,i=[],a=0,r=0;a<e.length;)if((t=e[a++])<128)i[r++]=String.fromCharCode(t);else if(t>191&&t<224)n=e[a++],i[r++]=String.fromCharCode((31&t)<<6|63&n);else if(t>239&&t<365){var o=((7&t)<<18|(63&(n=e[a++]))<<12|(63&(s=e[a++]))<<6|63&e[a++])-65536;i[r++]=String.fromCharCode(55296+(o>>10)),i[r++]=String.fromCharCode(56320+(1023&o))}else n=e[a++],s=e[a++],i[r++]=String.fromCharCode((15&t)<<12|(63&n)<<6|63&s);return i.join("")}var s={packUint64:function(e){var t=e/Math.pow(2,32),n=e%Math.pow(2,32);return new Uint8Array([(4278190080&t)>>>24,(16711680&t)>>>16,(65280&t)>>>8,255&t,(4278190080&n)>>>24,(16711680&n)>>>16,(65280&n)>>>8,255&n])},unpackUint64:function(e){return e instanceof ArrayBuffer&&(e=new Uint8Array(e)),256*(256*(256*(256*(256*(256*(256*e[0]+e[1])+e[2])+e[3])+e[4])+e[5])+e[6])+e[7]},stringToUtf8ByteArray:t,utf8ByteArrayToString:n,mergeArrayBufferList:function(e){if(0===e.length)return new Uint8Array([]).buffer;var t=0;e.forEach((function(e){t+=e.byteLength}));var n=new Uint8Array(t),s=0;return e.forEach((function(e){n.set(new Uint8Array(e),s),s+=e.byteLength})),n.buffer},convertByteUnit:function(e){var t=Math.round(e/1024),n="KB";return 1<=t/1024&&(t/=1024,n="MB"),{diff:t.toFixed(1),unit:n}},textEncode:function(e){return window.TextEncoder?(new TextEncoder).encode(e).buffer:new Uint8Array(t(e)).buffer},textDecode:function(e){return window.TextDecoder?(new TextDecoder).decode(e):n(new Uint8Array(e))}},i=null,a=null;function r(e){e&&(i=e,e.env.setWebRTC(this))}function o(){if(null!==a)return a;if(null==i)throw"synowebapi is null or undefined";return(a=i.create()).env.setCredential(i.env.getCredential()),a.env.setSynoToken(i.env.getSynoToken()),a}const l=Object.freeze({MESSAGE_TYPE_BYTE:0,MESSAGE_TYPE_STRING:1,MESSAGE_TYPE_EMPTY:99,MESSAGE_TYPE_HEADERS:100,MESSAGE_TYPE_STATUS:101,MESSAGE_TYPE_STATUSTEXT:102,MESSAGE_TYPE_UPLOAD_PROGRESS:248,MESSAGE_TYPE_ERROR:249,MESSAGE_TYPE_TERMINATE:250,MESSAGE_TYPE_PAUSE_STOP:251,MESSAGE_TYPE_PAUSE_CONTINUE:252,MESSAGE_TYPE_EOF:253,MESSAGE_TYPE_EOU:254,MESSAGE_TYPE_UNDEFINED:255}),h=Object.freeze({ERR_TYPE_SUCCESS:0,ERR_TYPE_UNMARSHAL:1,ERR_TYPE_INVALID_HELLO:2,ERR_TYPE_WEBAPI:252,ERR_TYPE_CONNECTION:253,ERR_TYPE_TIMEOUT:254,ERR_TYPE_UNKNWON:255});var c=function(){return new Promise((function(e,t){var n,s,i="Unknown";function a(t){e({isPrivate:t,browserName:i})}function r(e){return e===eval.toString().length}function o(){void 0!==navigator.maxTouchPoints?function(){var e=String(Math.random());try{window.indexedDB.open(e,1).onupgradeneeded=function(t){var n,s,i=null===(n=t.target)||void 0===n?void 0:n.result;try{i.createObjectStore("test",{autoIncrement:!0}).put(new Blob),a(!1)}catch(e){var r=e;return e instanceof Error&&(r=null!==(s=e.message)&&void 0!==s?s:e),a("string"==typeof r&&/BlobURLs are not yet supported/.test(r))}finally{i.close(),window.indexedDB.deleteDatabase(e)}}}catch(e){return a(!1)}}():function(){var e=window.openDatabase,t=window.localStorage;try{e(null,null,null,null)}catch(e){return a(!0)}try{t.setItem("test","1"),t.removeItem("test")}catch(e){return a(!0)}a(!1)}()}function l(){navigator.webkitTemporaryStorage.queryUsageAndQuota((function(e,t){var n;a(Math.round(t/1048576)<2*Math.round((void 0!==(n=window).performance&&void 0!==n.performance.memory&&void 0!==n.performance.memory.jsHeapSizeLimit?performance.memory.jsHeapSizeLimit:1073741824)/1048576))}),(function(e){t(new Error("detectIncognito somehow failed to query storage quota: "+e.message))}))}function h(){void 0!==self.Promise&&void 0!==self.Promise.allSettled?l():(0,window.webkitRequestFileSystem)(0,1,(function(){a(!1)}),(function(){a(!0)}))}void 0!==(s=navigator.vendor)&&0===s.indexOf("Apple")&&r(37)?(i="Safari",o()):function(){var e=navigator.vendor;return void 0!==e&&0===e.indexOf("Google")&&r(33)}()?(n=navigator.userAgent,i=n.match(/Chrome/)?void 0!==navigator.brave?"Brave":n.match(/Edg/)?"Edge":n.match(/OPR/)?"Opera":"Chrome":"Chromium",h()):void 0!==document.documentElement&&void 0!==document.documentElement.style.MozAppearance&&r(37)?(i="Firefox",a(void 0===navigator.serviceWorker)):void 0!==navigator.msSaveBlob&&r(39)?(i="Internet Explorer",a(void 0===window.indexedDB)):t(new Error("detectIncognito cannot determine the browser"))}))};function d(){const e=window.navigator.userAgent.toLowerCase();return!1===["chrome","chromium","crmo","crios","edg","ie","fxios","opera","opios","opr","droid","omniweb","arora","tizenoka","oculus","samsung","sailfish","huawei","kindle","lunascape","maxthon","netfront","jasmine","blazer","avant","slim","idu","qq","2345","metasr","lb","qi","obrowser","360","flock","rockmelt","midori","epiphany","silk","skyfire","ovibrowser","bolt","iron","vivaldi","iridium","phantomjs","bowser","quark","qupzilla","falkon","rekonq","puffin","brave","whale","qqbrowserlite","qq","duckduckgo","weibo","uc","qbcore","micromessenger","konqueror","trident","yabrowser","avast","avg","focus","opt","coc_coc","dolfin","coast","miuibrowser","comodo_dragon","electron","tesla","linkedin","fb","line","instagram","gsa"].some((t=>e.includes(t)))&&e.includes("safari")}async function u(e){var t=await navigator.serviceWorker.getRegistrations();if(0===t.length)return null;const n=e.substr(0,e.lastIndexOf("/")+1),s=t.filter((e=>{const t=new URL(e.scope,window.location.origin).pathname,s=t.indexOf(n);if(0>s)return!1;return 0>t.substr(s+n.length).indexOf("/")}));return 1<s.length&&g(`warning: multiple matched sw of ${n}`),0<s.length?s[0]:null}const p={enable:!1,pauseState:!1},E={...p},S={...p};function f(){return S.enable}function w(e,t){Object.defineProperty(e,"Enable",{set:e=>{null===function(e,t){var n=new RegExp("(?:(?:^|.*;\\s*)"+e+"\\s*\\=\\s*([^;]*).*$)|^.*$"),s=t.replace(n,"$1");return""===s?null:decodeURIComponent(s)}("id",window.document.cookie)?(t.enable=e,t.pauseState=e):t.enable=!1},get:()=>t.enable}),e.Pause=()=>{t.pauseState=t.enable,t.enable=!1},e.Resume=()=>{t.enable=t.pauseState}}var _=null;function g(){null===_&&T(),_.apply(null,arguments)}function T(){_=window.SYNO&&window.SYNO.Debug?window.SYNO.Debug:function(){const e=new URLSearchParams(window.location.search);for(let t of e.keys())if("jsDebug"===t)return!0;return!1}()?window.console.log:()=>{}}function v(e){var t=document.createElement("iframe");if(t.setAttribute("src",e),!1===t.src.startsWith(window.location.origin))throw`cannot send a cross domain request via webrtc: ${e}`;return t.src.replace(window.location.origin,"")}const m=new Set(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]);function b(e){const t={};return e.split("\n").forEach((e=>{const n=e.indexOf(":");if(n<0)return;const s=e.substr(0,n).trim(),i=e.substr(n+1).trim();if(s)if(t[s]){if(m.has(s))return;"set-cookie"===s?t["set-cookie"].push(i):t[s]+=", "+i}else"set-cookie"===s?t["set-cookie"]=[i]:t[s]=i})),t}class C{constructor(e,t,n,s,i){if(null==e)throw"clientId is null or undefined";if(null==t)throw"reqId is null or undefined";this.clientId=e,this.reqId=t,this.url=n,this.headers=new Map;for(const[e,t]of s.entries())this.headers.set(e,t);this.body=void 0===i?null:i}}class y extends C{constructor(e,t,n,s,i,a,r){super(e,t,n,s,i,a,r),this.redirected=!1,this.status=a,this.statusText=r}}class A extends EventTarget{constructor(){super(),this.resetLoadVars()}resetLoadVars(){this._loaded=0,this._total=0}setTotalSize(e){this._total=e}getTotalSize(){return this._total}updateProgress(){this.dispatchEvent(this.getProgressEvent("progress"))}getProgressEvent(e){return new ProgressEvent(e,{lengthComputable:0<this._total,loaded:this._loaded,total:this._total})}}class R extends A{constructor(){super(),this.initEvents()}initEvents(){this.addEventListener("loadstart",(e=>{null!=this.onloadstart&&this.onloadstart(e)})),this.addEventListener("progress",(e=>{null!=this.onprogress&&this.onprogress(e)})),this.addEventListener("abort",(e=>{null!=this.onabort&&this.onabort(e)})),this.addEventListener("error",(e=>{null!=this.onerror&&this.onerror(e)})),this.addEventListener("load",(e=>{null!=this.onload&&this.onload(e)})),this.addEventListener("timeout",(e=>{null!=this.ontimeout&&this.ontimeout(e)})),this.addEventListener("loadend",(e=>{null!=this.onloadend&&this.onloadend(e)}))}}var k=null;class I extends A{constructor(e){super(),this.webrtc=e,this.taskId=e.taskManager.newTaskId(),this.resetVars(),this.initEvents(),this.upload=new R}resetVars(){this.timeout=0,this.timeoutId=0,this._url="",this._method="POST",this._redirect=!1,this._statusCode=0,this._statusText="",this._data=null,this._response=null,this._responseText=null,this._responseType="",this._reqHeaders={},this._reqHeadersSet=new Set,this._reqContentType="",this._resHeaders={},this._state=I.XHR_STATE_UNSENT,this._ignoreSizeCheck=!1,this._isPause=!1,this.resetLoadVars()}setTaskTimeout(e){null==e||0>e||(this.timeout=e)}startTimeout(){0>=this.timeout||(this.stopTimeout(),this.timeoutId=setTimeout((()=>{this._onTimeout()}),this.timeout))}stopTimeout(){0!==this.timeoutId&&clearTimeout(this.timeoutId),this.timeoutId=0}setStatusCode(e){this.stopTimeout(),this._statusCode=parseInt(e),this.changeState(I.XHR_STATE_HEADERS_RECEIVED)}setStatusText(e){this._statusText=e}setResponseHeaders(e){"string"==typeof e&&(e=JSON.parse(e));var t={};for(let n of Object.entries(e))t[n[0].toLowerCase()]=n[1];this._resHeaders=t,this._handleContentLength(),this._handleSetCookies(),this._onReceiveHeaders()}updateUploadProgress(e){this.upload._loaded+=e,this.upload.updateProgress(),this.upload._total===this.upload._loaded&&this.upload.dispatchEvent(this.upload.getProgressEvent("load"))}_handleContentLength(){const e=this._resHeaders["content-length"];void 0!==e&&(this.setTotalSize(parseInt(e)),this.setIgnoreSizeCheck(!1))}_handleSetCookies(){const e=this._resHeaders["set-cookie"];void 0!==e&&e.forEach((e=>{if(e.includes("HttpOnly"))if(e.includes("id=")){var t=new Date;if(null!==k&&6e4>t-k)return;k=t,o().request({api:"SYNO.Core.Desktop.Timeout",method:"reset",version:1})}else g("cannot set-cookie with HttpOnly:",e);else document.cookie=e}))}changeState(e){if(I.XHR_STATE_UNSENT>e||I.XHR_STATE_DONE<e)throw"Invalid task request state";this._state!==e&&(this._state=e,this.dispatchEvent(new Event("readystatechange")),I.XHR_STATE_LOADING===e&&this.dispatchEvent(this.getProgressEvent("loadstart")))}close(){I.XHR_STATE_UNSENT!==this._state&&I.XHR_STATE_DONE!==this._state&&(this.dispatchEvent(this.getProgressEvent("loadend")),this.upload.dispatchEvent(this.upload.getProgressEvent("loadend"))),this.stopTimeout(),this.webrtc.taskManager.removeTaskRequest(this.taskId),this.changeState(I.XHR_STATE_DONE)}setIgnoreSizeCheck(e){this._ignoreSizeCheck=e}_onReceiveHeaders(){null!=this.onReceiveHeaders&&this.onReceiveHeaders()}_onMessage(e,t){null!=this.onMessage&&l.MESSAGE_TYPE_EOF!==t&&this.onMessage(e,t),!1===this._ignoreSizeCheck&&0<this._total&&this._total<this._loaded?this._onError("unexpected amount of data"):(l.MESSAGE_TYPE_EOF!==t&&("none"===this.responseType?this._data=null:"blob"===this.responseType?(this._data=null==this._data?[]:this._data,this._data.push(new Blob([e]))):null==this._data?this._data=e:this._data=s.mergeArrayBufferList([this._data,e]),"arraybuffer"===this.responseType&&I.BLOB_CHUNK_SIZE<this._data.byteLength&&(g("Response data are truncated."),this._data=e)),(0<this._total&&this._total===this._loaded||l.MESSAGE_TYPE_EOF===t)&&(this.dispatchEvent(this.getProgressEvent("load")),this.close()))}_onChunk(e,t){this.changeState(I.XHR_STATE_LOADING),this._loaded+=e,null!=this.onChunk&&this.onChunk(e,t)}_onError(e){var t=new ErrorEvent("error",{error:"string"==typeof e?new Error(e):e});this.dispatchEvent(this.getProgressEvent("error")),this.upload.dispatchEvent(this.upload.getProgressEvent("error")),this.close(),null!=this.onError&&this.onError(t)}_onTimeout(){this.dispatchEvent(this.getProgressEvent("timeout")),this.upload.dispatchEvent(this.upload.getProgressEvent("timeout")),null!=this.onTimeout&&this.onTimeout()}pause(){!1!==this._pauseCheck(!1)&&(this.webrtc.dcSendPause(this.taskId),this._isPause=!0)}resume(){!1!==this._pauseCheck(!0)&&(this.webrtc.dcSendResume(this.taskId),this._isPause=!1)}_pauseCheck(e){return I.XHR_STATE_LOADING===this._state&&e===this._isPause}get status(){return this._statusCode}get statusText(){return this._statusText}set responseType(e){const t=new Set(["arraybuffer","blob","document","json","text","none"]);var n=e.toLowerCase();t.has(n)?this._responseType=n:(g(`Fail to set responseType to ${e}`),this._responseType="")}get responseType(){return this._responseType}get responseText(){return null===this._data?"":(null===this._responseText&&(this._data instanceof ArrayBuffer?this._responseText=s.textDecode(this._data):"string"==typeof this._data?this._responseText=this._data:g("fail to decode responseText: unknown type")),this._responseText)}get response(){if(null===this._data)return""===this.responseType||"text"===this.responseType?"":null;if(null===this._response)try{switch(this.responseType){case"":case"text":this._response=this.responseText;break;case"arraybuffer":case"blob":"string"==typeof this._data?this._response=s.textEncode(this._data):this._response=this._data,"blob"===this.responseType&&(this._response=new Blob(this._response instanceof Array?this._response:[this._response]));break;case"json":this._response=JSON.parse(this.responseText);break;case"document":this._response=(new DOMParser).parseFromString(this.responseText,"text/xml");break;default:this._response=void 0}}catch(e){return g("fail to handle response:",e),null}return this._response}get responseXML(){const e=this._resHeaders["content-type"];var t="text/xml";null!=e&&e.includes("application/xml")&&(t="application/xml");var n=(new DOMParser).parseFromString(this.responseText,t);return n.querySelector("parsererror")?null:n}get readyState(){return this._state}open(e,t,n,s,i){let a=arguments.length>5&&void 0!==arguments[5]&&arguments[5];I.XHR_STATE_UNSENT!==this._state&&this.abort(),null==s&&null==i||g("user or password param is not supported by TaskRequest"),this._method=e,this._url=t,this._redirect=a,this.changeState(I.XHR_STATE_OPENED)}async send(e){if(I.XHR_STATE_OPENED!==this._state)throw"The object's state must be OPENED.";var t=this.taskId,n=await this.webrtc.getChannelByBody(e),s={pathUrl:v(this._url),httpMethod:this._method,headers:this._reqHeaders,upload:this._isUploadRequest(e),bodySize:this._getBodySize(e),protocolVersion:2,redirect:this._redirect};return this.startTimeout(),await n.dcSend(JSON.stringify(s),t),{taskId:t,channel:n}}_isUploadRequest(e){return e instanceof FormData||this._reqContentType.toLowerCase().includes("multipart")}_getBodySize(e){if(this._reqContentType.toLowerCase().includes("multipart")){if(e instanceof ArrayBuffer)return e.byteLength;if(ArrayBuffer.isView(e))return e.buffer.byteLength;if(e instanceof Blob)return e.size}return 0}abort(){I.XHR_STATE_UNSENT!==this._state&&I.XHR_STATE_DONE!==this._state&&(this.dispatchEvent(new Event("abort")),this.upload.dispatchEvent(new Event("abort")),this.webrtc.dcTerminate(this.taskId),this.close(),this.taskId=this.webrtc.taskManager.newTaskId(),this.webrtc.taskManager.addTaskRequest(this),this.resetVars())}getAllResponseHeaders(){var e="";for(let[t,n]of Object.entries(this._resHeaders))"set-cookie"!==t&&n.forEach((n=>{e+=t+": "+n+"\r\n"}));return e}getResponseHeader(e){if("set-cookie"===(e=e.toLowerCase()))throw'Refused to get unsafe header "set-cookie"';var t=this._resHeaders[e];return null==t?null:t[0]}_getResponseHeadersObj(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const t=new Headers;for(const[n,s]of Object.entries(this._resHeaders))!0===e&&"set-cookie"===n||s.forEach((e=>{t.append(n,e)}));return t}setRequestHeaders(e){let t=null;t=Headers&&e instanceof Headers||Map&&e instanceof Map?e.entries():Object.entries(e);for(const[e,n]of t)this.setRequestHeader(e,n)}setRequestHeader(e,t){var n=e.toLowerCase();!1===this._reqHeadersSet.has(n)&&(this._reqHeaders[e]=String(t),this._reqHeadersSet.add(n),"content-type"===n&&(this._reqContentType=String(t)))}initEvents(){this.addEventListener("abort",(e=>{null!=this.onabort&&this.onabort(e)})),this.addEventListener("error",(e=>{null!=this.onerror&&this.onerror(e)})),this.addEventListener("load",(e=>{null!=this.onload&&this.onload(e)})),this.addEventListener("loadstart",(e=>{null!=this.onloadstart&&this.onloadstart(e)})),this.addEventListener("progress",(e=>{null!=this.onprogress&&this.onprogress(e)})),this.addEventListener("timeout",(e=>{null!=this.ontimeout&&this.ontimeout(e)})),this.addEventListener("loadend",(e=>{null!=this.onloadend&&this.onloadend(e)})),this.addEventListener("readystatechange",(e=>{null!=this.onreadystatechange&&this.onreadystatechange(e)}))}}e(I,"XHR_STATE_UNSENT",0),e(I,"XHR_STATE_OPENED",1),e(I,"XHR_STATE_HEADERS_RECEIVED",2),e(I,"XHR_STATE_LOADING",3),e(I,"XHR_STATE_DONE",4),e(I,"BLOB_CHUNK_SIZE",65534);class L extends I{constructor(e){super(e)}async send(e){var{taskId:t,channel:n}=await super.send(e);if(this.upload.resetLoadVars(),this.upload.dispatchEvent(this.upload.getProgressEvent("loadstart")),null==e)await n.dcSend(e,t);else if("string"==typeof e)this.upload._total=s.textEncode(e).byteLength,await n.dcSend(e,t);else if(e instanceof URLSearchParams){var i=e.toString();this.upload._total=s.textEncode(i).byteLength,await n.dcSend(i,t)}else if(e instanceof ArrayBuffer)this.upload._total=e.byteLength,await this._sendBlob(new Blob([e]),n,t);else if(ArrayBuffer.isView(e)){var a=e.buffer;this.upload._total=a.byteLength,await this._sendBlob(new Blob([a]),n,t)}else e instanceof Blob?(this.upload._total=e.size,await this._sendBlob(e,n,t)):e instanceof FormData?await this._sendFormData(e,n,t):g("fail to send data with unknown data");!0===this._isUploadRequest(e)&&n.dcSendEOU(t)}async _sendFormData(e,t,n){var i={},a={},r={};for(let t of e.entries()){let e=t[0],n=t[1];if(n instanceof Blob){let t=null==n.name?"blob":n.name;a[e]={name:t,blob:n},r[e]={name:t,size:n.size}}else"string"==typeof n?i[e]=n:g("Invalid form data:",e)}var o=0,l=JSON.stringify(i),h=JSON.stringify(r);o=s.textEncode(l).byteLength,o+=s.textEncode(h).byteLength;for(let e of Object.entries(a))o+=s.textEncode(e[0]).byteLength,o+=s.textEncode(e[1].name).byteLength,o+=e[1].blob.size;if(this.upload._total=o,await t.dcSend(l,n)&&await t.dcSend(h,n))for(let e of Object.entries(a)){if(!await t.dcSend(e[0],n))return;if(!await t.dcSend(e[1].name,n))return;if(!await this._sendBlob(e[1].blob,t,n))return}}async _sendBlob(e,t,n){const s=I.BLOB_CHUNK_SIZE;var i=e.size,a=Math.floor(i/s),r=i%s,o=null,l=null;for(let i=1;i<=a;i++)if(o=e.slice((i-1)*s,i*s),l=await o.arrayBuffer(),!await t.dcSend(l,n))return!1;return o=e.slice(a*s,a*s+r),l=await o.arrayBuffer(),!!await t.dcSend(l,n)&&(t.dcSendEOF(n),!0)}}class M{constructor(){const e=Math.floor(Math.random()*M.CACHE_BUSTING_MAX);this.swLauncher=null,this.swLauncherUrl=M.SW_LAUNCHER+"?v="+e,this.swVersion=null,this.disableCache=!1,this.context=null,this.webrtcChannel=null,this.isSwReportEventRegistered=!1,this.updateServiceWorker()}async updateServiceWorker(){if(!1===this.isSupport())return;const e=await u(this.swLauncherUrl);null!=e&&(navigator.serviceWorker.addEventListener("controllerchange",(async e=>{g("[webrtc cache] update cache service worker");const t=this.webrtcChannel;await this.reset(),null!=t&&await this.init(t)})),e.update())}async unregisterServiceWorker(){const e=await u(this.swLauncherUrl);null!=e&&(await this.flushCache(),await e.unregister(),g("[webrtc cache] unregister service worker"))}async flushCache(){if(!1===this.isSupport())return;null!=await u(this.swLauncherUrl)&&await this.postToServiceWorker({flushCache:!0})}isSupport(){return!0!==this.disableCache&&(!d()&&!!(isSecureContext&&MessageChannel&&navigator.serviceWorker&&Headers&&Request&&Response&&Cache&&IDBFactory))}async isSwInstalled(){if(!1===this.isSupport())return!1;const e=await u(this.swLauncherUrl);return null!=e}async reset(){this.swLauncher&&(await this.postToServiceWorker({unbind:!0}),this.removeIframe(this.swLauncher),this.swLauncher=null,this.context=null,this.webrtcChannel=null)}async init(e,t){null!=e?!1!==this.isSupport()?(this.swLauncher&&(g("[webrtc] cache has been inited"),await this.reset()),this.webrtcChannel=e,this.loadSwLauncher(t),this.connectToServiceWorker()):g("[webrtc] not support cache"):g("[webrtc] webrtcInst is null or undefined")}connectToServiceWorker(){this.context={channel:new MessageChannel},this.listenServiceWorker(this.context),this.sendContextToServiceWorker(this.context)}listenServiceWorker(e){window.addEventListener("beforeunload",(async e=>{await this.postToServiceWorker({unbind:!0}),g("[webrtc cache] window unbinding")}));const t=e.channel.port1;t.onmessage=async e=>{if(e.data.bindRequest){const{launcherClientId:t,version:n}=e.data.bindRequest;null===this.swVersion||n.split(".")[0]===this.swVersion.split(".")[0]?(await this.postToServiceWorker({bindAcceptV2:{launcherClientId:t,appName:window._S?window._S("standaloneAppName"):""}}),this.swVersion=n,g("[webrtc cache] window binding")):await this.postToServiceWorker({bindReject:t})}else if(e.data.fetchRequest){const n=e.data.fetchRequest,s={clientId:n.clientId,reqId:n.reqId};if(!0!==E.enable||!0!==f())return void t.postMessage({fetchReject:s});t.postMessage({fetchAccept:s}),s.respInfo=null;try{s.respInfo=await this.webrtcFetch(n)}catch(e){g("[webrtc] cache fetch error",e)}t.postMessage({fetchDone:s})}else g("[webrtc] unknown cache message channel command")}}async webrtcFetch(e){var t,n;const s=new Promise(((e,s)=>{t=e,n=s})),i=this.webrtcChannel.newTaskRequest();return i.setRequestHeaders(e.headers),i.responseType="blob",i.onload=n=>{const s=new y(e.clientId,e.reqId,e.url,i._getResponseHeadersObj(),i.response,i.status,i.statusText);t(s)},i.onError=e=>{n(e)},i.open(e.method,e.url,!0,null,null,"follow"===e.redirect),i.send(e.body),s}async postToServiceWorker(e){const t=navigator.serviceWorker.controller;null!=t?t.postMessage(e):g("cache sw is not active")}sendContextToServiceWorker(e){const t=[null,"*",[e.channel.port2]];this.swLauncher.loaded?this.swLauncher.postMessage(...t):this.swLauncher.addEventListener("load",(()=>{this.swLauncher.postMessage(...t)}),{once:!0})}loadSwLauncher(e){if(null!==this.swLauncher)return;const t=new XMLHttpRequest;t.open("HEAD",this.swLauncherUrl),t.onload=()=>{200!==t.status&&this.handleSwLauncherFailure(e)},t.onerror=()=>{this.handleSwLauncherFailure(e)},t.send(),this.swLauncher=this.makeIframe(this.swLauncherUrl)}handleSwLauncherFailure(e){this.disableCache=!0,e&&e(`cannot get ${M.SW_LAUNCHER}`)}makeIframe(e){if(!e)throw new Error("src is undefined");const t=document.createElement("iframe");return t.hidden=!0,t.src=e,t.loaded=!1,t.name="WebrtcCacher",t.isIframe=!0,t.postMessage=function(){t.contentWindow.postMessage(...arguments)},t.addEventListener("load",(()=>{t.loaded=!0}),{once:!0}),document.body.appendChild(t),t}removeIframe(e){null!==e&&setTimeout((()=>{document.body.removeChild(e)}),M.IFRAME_REMOVE_DELAY)}registerSwReportStatisticsEvent(){!1===this.isSwReportEventRegistered&&(window.addEventListener("beforeunload",(async e=>{fetch(new URL(M.REPORT_TRIGGER_PATH,window.location.origin),{keepalive:!0})})),this.isSwReportEventRegistered=!0)}}e(M,"SW_LAUNCHER","/cacheLauncher.html"),e(M,"IFRAME_REMOVE_DELAY",3e3),e(M,"CACHE_BUSTING_MAX",9999),e(M,"REPORT_TRIGGER_PATH","scripts/synowebrtc/WebrtcCacher/ReportStatistics");const x=new M;var O=1;class N extends EventTarget{constructor(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(super(),this.hasError=!1,this.ignoreError=!1,this.wsCmdTable=new Map,this.signalAddr="",this.sharing=e,this.helloInfo="",this.ws=null,this.statistics=new D,""===t)this.signalId=O++,this.signalSessionIdBase=function(e){var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",n="";for(let s=0;s<e;s++)n+=t.charAt(Math.floor(Math.random()*t.length));return n}(32);else{const e=t.split("@");this.signalId=parseInt(e[1]),this.signalSessionIdBase=e[0]}}start(){o().request({api:this.sharing?"SYNO.WebRTC.Proxy.Sharing":"SYNO.WebRTC.Proxy",method:"signal",version:1,callback:(e,t)=>{e&&null!=t.host&&null!=t.port?(this.signalAddr=t.host+":"+t.port,this.ws=new WebSocket("wss://"+this.signalAddr),this.ws.onopen=e=>{this.onWsOpen(e)},this.ws.onclose=e=>{this.onWsClose(e)},this.ws.onmessage=e=>{this.onWsMessage(e)},this.ws.onerror=e=>{this._onWsError(e)}):this._onWsError("fail to get signal server info")}})}wsSend(e){null!==this.ws?this.ws.send(e):g("websocket is null")}async onWsOpen(e){const{isPrivate:t}=await c();this.helloInfo={version:1,isMobile:!!window._S&&window._S("isMobile"),app:window._S?window._S("standaloneAppName"):"",referer:window.location.href,isIncognito:t,isCacheSwInstalled:await x.isSwInstalled()};const n=this.makeMessage("browser_hello",this.helloInfo);this.wsSend(n),this.dispatchEvent(new Event("open"))}onWsClose(e){this.dispatchEvent(new Event("close"))}onWsMessage(e){try{const t=JSON.parse(e.data),n=t.cmd,s=t.param;if(null==n)return void g("null command");const i=this.wsCmdTable.get(n);if(null==i)return void g("unknown command");i(s)}catch(e){this._onWsError(e)}}_onWsError(e){!0!==this.ignoreError&&(this.hasError=!0,g("signal server error:",e),this.dispatchEvent(new Event("error")))}setIgnoreError(e){this.ignoreError=e}registerWsCmd(e,t){this.wsCmdTable.set(e,t)}sendIceCandidate(e){if(null!==e.candidate&&null!=e.candidate.candidate){const t=this.makeMessage("ice_exchange",JSON.stringify(e.candidate.candidate));this.wsSend(t)}}sendAnswerDesc(e){const t=this.makeMessage("browser_answer",JSON.stringify(e));this.wsSend(t)}sendWebrtcStatus(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;if(null===this.helloInfo||void 0===this.helloInfo||null===this.signalAddr||void 0===this.signalAddr)return;const n={type:"status",data:{...this.helloInfo,error:t}};this.sendCorsResult(n)}sendStatistics(e){if(null===this.statistics||void 0===this.statistics||null===this.signalAddr||void 0===this.signalAddr)return;e instanceof D&&(e=[e]),Array.isArray(e)&&e.forEach((e=>{this.statistics.merge(e)}));const t={type:"statistics",data:this.statistics.toPlainObj()};this.sendCorsResult(t),this.statistics=null}sendCorsResult(e){fetch&&fetch("https://"+this.signalAddr,{mode:"no-cors",method:"POST",body:JSON.stringify(e),keepalive:!0}).catch((e=>{g("fail to upload result",e)}))}makeMessage(e,t){if(e)return t||(t=null),JSON.stringify({cmd:e,sid:this.getSignalSessionID(),param:t});g("cmd or sessionId is null or empty")}getSignalSessionID(){return this.signalSessionIdBase+"@"+this.signalId}getSignalAddr(){return this.signalAddr}close(){null!=this.ws&&this.ws.close()}}class D{constructor(e){if(null!=e)return this.startTime=e.startTime,this.txStatsText=e.txStatsText,this.rxStatsText=e.rxStatsText,this.txStatsBinary=e.txStatsBinary,void(this.rxStatsBinary=e.rxStatsBinary);this.startTime=new Date,this.txStatsText=0,this.rxStatsText=0,this.txStatsBinary=0,this.rxStatsBinary=0}addTxText(e){this.txStatsText+=e}addRxText(e){this.rxStatsText+=e}addTxBinary(e){this.txStatsBinary+=e}addRxBinary(e){this.rxStatsBinary+=e}merge(e){this.txStatsText+=e.txStatsText,this.rxStatsText+=e.rxStatsText,this.txStatsBinary+=e.txStatsBinary,this.rxStatsBinary+=e.rxStatsBinary}toPlainObj(){return{pcUploadText:this.txStatsText,pcDownloadText:this.rxStatsText,pcUploadBinary:this.txStatsBinary,pcDownloadBinary:this.rxStatsBinary,duration:new Date-this.startTime}}}class P{constructor(e){this.taskIdCnt=1,this.taskRequestTable=new Map}newTaskId(){return this.taskIdCnt++}addTaskRequest(e){e instanceof I?this.taskRequestTable.set(e.taskId,e):g("wrong type of taskRequest")}removeTaskRequest(e){this.taskRequestTable.delete(e)}getTaskRequest(e){var t=this.taskRequestTable.get(e);return t||null}getTaskRequestTable(){return this.taskRequestTable}}class U{constructor(){this.semaphoreTable=new Map}getSempaphore(e){return void 0===this.semaphoreTable.get(e)&&this.initSemaphoreCls(e),new(this.semaphoreTable.get(e))}initSemaphoreCls(e){var t=function(){let e=Promise.resolve();return class{constructor(){let t,n=e,s=new Promise((e=>{t=e}));e=e.then((()=>s)),this.start=function(){return n},this.end=function(){t()}}}}();this.semaphoreTable.set(e,t)}}class W{constructor(){this.webrtcTable=new Map,this.eventTable=new Map,this.failureTable=new Map,this.giveupTable=new Set,this.registerWindowUnloadEvent()}registerWindowUnloadEvent(){window.addEventListener("beforeunload",(()=>{for(const[e,t]of this.webrtcTable)null!=t&&t.close()}))}get(e){return this.webrtcTable.get(e)}_getEventTarget(e){var t=this.eventTable.get(e);return null==t?(g(`[webrtc] cannot find ${e} in the event table`),null):t}set(e,t){this.get(e)&&this.remove(e),this.webrtcTable.set(e,t),this.eventTable.set(e,new EventTarget),this.failureTable.set(e,new H),this._initEvents(e,t)}_initEvents(e,t){var n=setTimeout((()=>{g(`[webrtc] ${e} connection timeout`),this.failureTable.get(e).genNextConnectionFailure(),this._dispatchEventCallback(e,"timeout")}),W.CONNECTION_CREATE_TIMEOUT);t.addEventListener("channelopen",(()=>{clearTimeout(n),this._dispatchEventCallback(e,"channelopen")})),t.addEventListener("channelclose",(()=>{this._dispatchEventCallback(e,"channelclose")})),t.addEventListener("signalerror",(()=>{clearTimeout(n),this._dispatchEventCallback(e,"signalerror")}))}_dispatchEventCallback(e,t){var n=this._getEventTarget(e);null!==n&&n.dispatchEvent(new Event(t))}registerEventCallbacks(e,t){var n=this._getEventTarget(e);null!==n&&(t.channelopen&&n.addEventListener("channelopen",t.channelopen),t.channelclose&&n.addEventListener("channelclose",t.channelclose),t.signalerror&&n.addEventListener("signalerror",t.signalerror),t.timeout&&n.addEventListener("timeout",t.timeout))}remove(e){this.webrtcTable.get(e)&&this.webrtcTable.get(e).close(),this.webrtcTable.delete(e),this.eventTable.delete(e),this.failureTable.delete(e)}giveup(e){this.giveupTable.add(e),this.remove(e),g(`[webrtc] ${e} give up`)}isGiveup(e){return this.giveupTable.has(e)}inFailureCooldown(e){const t=this.failureTable.get(e);return!!t.hasConnectionFailure()&&new Date-t.lastFailureDate<t.failureCooldown}isMaxFailureCooldown(e){const t=this.failureTable.get(e);return H.MAX_FAILURE_COOLDOWN_INTERVAL===t.failureCooldown}}e(W,"CONNECTION_CREATE_TIMEOUT",3e4);class H{constructor(){this.failureCooldown=H.DEFAULT_FAILURE_COOLDOWN_INTERVAL,this.lastFailureDate=null}hasConnectionFailure(){return null!==this.lastFailureDate}genNextConnectionFailure(){null!==this.lastFailureDate&&(this.failureCooldown=Math.min(2*this.failureCooldown,H.MAX_FAILURE_COOLDOWN_INTERVAL)),this.lastFailureDate=new Date}}e(H,"MAX_FAILURE_COOLDOWN_INTERVAL",6e4),e(H,"DEFAULT_FAILURE_COOLDOWN_INTERVAL",1e3);const F=new W;class B extends EventTarget{constructor(e){if(super(),Object.assign(this,e),null==this.name||null==this.sharing||null==this.reconnect||null==this.aux)throw"name, sharing, reconnect, or aux attribute is null";this.resetDcRecv(),this.taskManager=new P,this.semaphoreManager=new U,this.isFailureReported=!1,this.auxChannel=null;var t="";if(this.isAuxChannel()){var n=this.getMainChannel();if(null==n||n.isDataChannelClose())return void g("fail to init aux channel since main channel is not opend");t=n.getSignalSessionID(),this.taskManager=n.taskManager}this.peerConnection=null,this.dc=null,this.iceServers={iceServers:[{urls:B.STUN_SERVER_ADDR}]},this.createServerConnection(),this.sc=new N(this.sharing,t),this.initSc(),this.pingpongTimeoutId=-1,this.startICE()}startICE(){this.pingpong({success:()=>{this.sc.start(),this.pingpongTimeoutId=-1},fail:()=>{g("[webrtc] pingpong failure"),this.pingpongTimeoutId=setTimeout((()=>{this.startICE()}),B.PINGPONG_INTERVAL)}})}pingpong(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:B.PINGPONG_TIMEOUT;var n=new XMLHttpRequest;n.open("GET","webman/pingpong.cgi"),n.timeout=t,e.success&&(n.onload=e.success),e.fail&&(n.ontimeout=e.fail,n.onerror=e.fail),n.send()}newTaskRequest(){var e=new L(this);return this.taskManager.addTaskRequest(e),e}async getChannelByBody(e){return!1===this.aux?this:(e instanceof ArrayBuffer||ArrayBuffer.isView(e)||e instanceof Blob||e instanceof FormData)&&null!=this.auxChannel&&this.auxChannel.isDataChannelOpen()?this.auxChannel:this}isDefaultMainChannel(){return B.DEFAULT_CHANNEL_NAME===this.name&&!1===this.isAuxChannel()}isAuxChannel(){return this.name.endsWith(B.AUX_CHANNEL_POSTFIX)}getMainChannel(){if(this.isAuxChannel()){var e=this.name.substr(0,this.name.indexOf(B.AUX_CHANNEL_POSTFIX));return F.get(e)}return null}getAuxChannel(){return!1===this.isAuxChannel()?F.get(this.name+B.AUX_CHANNEL_POSTFIX):null}async startAuxChannel(){var e=await q(this.name+B.AUX_CHANNEL_POSTFIX,this.sharing,!1,!1,!1);if(null!=e&&e.isDataChannelOpen())return this.auxChannel=e}async waitForReady(){if(!0!==this.isDataChannelOpen())return new Promise(((e,t)=>{const n=setInterval((()=>{!0===this.isDataChannelOpen()&&(clearInterval(n),e())}),100)}))}close(){0<this.pingpongTimeoutId&&(clearTimeout(this.pingpongTimeoutId),this.pingpongTimeoutId=-1),null!==this.sc&&this.sc.close(),null!==this.peerConnection&&this.peerConnection.close(),null!==this.dc&&(this.dc.close(),this.reportStatistics())}isDataChannelOpen(){return null!==this.dc&&"open"===this.dc.readyState&&null!==this.peerConnection&&"connected"===this.peerConnection.connectionState}isDataChannelClose(){return null!==this.dc&&("closing"===this.dc.readyState||"closed"===this.dc.readyState)}isConnectionFinished(){if(null==this.sc||null==this.peerConnection)return g("signal client or peer connection is null"),!1;var e=this.peerConnection.connectionState;return!0===this.sc.hasError||"disconnected"===e||"failed"===e||"closed"===e}isSharingConnection(){return!0===this.sharing}getSignalSessionID(){return this.sc.getSignalSessionID()}getSignalAddr(){return this.sc.getSignalAddr()}initSc(){this.initScCmd(),this.sc.addEventListener("close",(()=>{null!==this.peerConnection&&null!==this.dc&&this.isDataChannelOpen()||this.dispatchEvent(new Event("signalerror"))})),this.sc.addEventListener("error",(()=>{this.dispatchEvent(new Event("signalerror")),this.reportStatus(!1,h.ERR_TYPE_CONNECTION)}))}initScCmd(){this.sc.registerWsCmd("signal_echo",(e=>{let t=null;try{t=JSON.parse(e)}catch(n){t=e}var n;!0==t instanceof Object?0===t.error?(this.onSignalServerReady(),n=t.cache,S.enable=n,this.isDefaultMainChannel()&&(!0===t.flushCache&&x.flushCache(),!0===t.unregisterCache&&x.unregisterServiceWorker())):(g("signal echo error"),this.reportStatus(!1,t.error),this.close()):"ok"===t?this.onSignalServerReady():(g("signal echo error"),this.reportStatus(!1,h.ERR_TYPE_UNKNWON),this.close())})),this.sc.registerWsCmd("dsm_offer",(e=>{const t=JSON.parse(e);this.peerConnection.setRemoteDescription(t),this.peerConnection.createAnswer().then(this.offerAnswer.bind(this),this.onCreateSessionDescriptionError.bind(this))})),this.sc.registerWsCmd("ice_exchange",(e=>{const t=JSON.parse(e);this.peerConnection.addIceCandidate(new RTCIceCandidate(t)).then(this.onAddIceCandidateSuccess.bind(this),this.onAddIceCandidateError.bind(this))}))}reportStatus(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:h.ERR_TYPE_SUCCESS;if(this.isDefaultMainChannel()){if(h.ERR_TYPE_SUCCESS!==t&&!0===this.isFailureReported)return;this.sc.sendWebrtcStatus(e,t),h.ERR_TYPE_SUCCESS!==t?this.isFailureReported=!0:this.isFailureReported=!1}}reportStatistics(){if(this.isDefaultMainChannel()){const t=this.getAuxChannel();let n=null;var e;if(null!=t)n=null==t||null===(e=t.sc)||void 0===e?void 0:e.statistics;this.sc.sendStatistics(n)}}onSignalServerReady(){o().request({api:this.isSharingConnection()?"SYNO.WebRTC.Proxy.Sharing":"SYNO.WebRTC.Proxy",method:"create",version:1,params:{sid:this.getSignalSessionID()},callback:(e,t)=>{e||(g("WebRTC api fail: "+t),this.dispatchEvent(new Event("signalerror")),this.reportStatus(!1,h.ERR_TYPE_WEBAPI))}})}createServerConnection(){this.peerConnection=new RTCPeerConnection(this.iceServers),this.peerConnection.onconnectionstatechange=e=>{g("[webrtc] peer connection state",this.name,this.peerConnection.connectionState),"failed"!==this.peerConnection.connectionState&&"closed"!==this.peerConnection.connectionState||null==this.dc||"closed"===this.dc.readyState||this.close()},this.peerConnection.onicecandidate=e=>{this.onIceCandidate(this.peerConnection,e)},this.peerConnection.ondatachannel=this.receiveChannelCallback.bind(this)}onIceCandidate(e,t){this.sc.sendIceCandidate(t)}offerAnswer(e){this.peerConnection.setLocalDescription(e),this.sc.sendAnswerDesc(e)}onCreateSessionDescriptionError(e){g("fail to create session description: "+e.toString())}onAddIceCandidateSuccess(){}onAddIceCandidateError(e){g("fail to add Ice Candidate:",e.toString())}receiveChannelCallback(e){this.dc=e.channel,this.dc.onmessage=this._onDataChannelReceive.bind(this),this.dc.onopen=()=>{this.sc.setIgnoreError(!0),this.sc.close(),this._onDataChannelOpen()},this.dc.onclose=()=>{this._onDataChannelClose()},this.dc.bufferedAmountLowThreshold=B.BUFFERED_AMOUNT_LOW_THRESHOLD}_onDataChannelOpen(){if(this._onReceiveChannelStateChange(),this.reportStatus(!0),this.isAuxChannel()){var e=this.getMainChannel();if(null==e||e.isDataChannelClose())return g("close aux channel since main channel is not open"),void this.close()}else!0===this.aux&&this.startAuxChannel(),this.isDefaultMainChannel()&&f()&&x.init(this),x.registerSwReportStatisticsEvent();this.dispatchEvent(new Event("channelopen"))}_onDataChannelClose(){this.taskManager.getTaskRequestTable().forEach(((e,t)=>{I.XHR_STATE_OPENED<=e._state&&I.XHR_STATE_LOADING>=e._state&&e._onError("data channel is closed")})),this.isAuxChannel()||null==this.auxChannel||this.auxChannel.close(),this._onReceiveChannelStateChange(),this.isDefaultMainChannel()&&f()&&x.reset(),this.dispatchEvent(new Event("channelclose")),this.reportStatistics()}_onReceiveChannelStateChange(){const e=this.dc.readyState;g("[webrtc]",this.name,"receive channel state is:",e)}onDataChannelReceive(e,t,n){var s=this.taskManager.getTaskRequest(n);null!==s&&s._onMessage(e,t)}onDataChannelChunk(e,t,n){var s=this.taskManager.getTaskRequest(n);null!==s&&s._onChunk(e,t)}onDataChannelError(e,t){var n=this.taskManager.getTaskRequest(t);null!==n&&n._onError(e)}async dcSendWrapper(e,t){if(!this.taskManager.getTaskRequest(e))return!1;var n=!1;if(this.isDataChannelOpen()){var s=this.semaphoreManager.getSempaphore("dcSend");await s.start();try{n=await t()}finally{s.end()}}else g("webrtc datachannel is closed or has not been opened");return n}async dcSend(e,t){return await this.dcSendWrapper(t,(async()=>{var n=null,i=null;if("string"==typeof e?(n=s.textEncode(e),i=l.MESSAGE_TYPE_STRING,null!==this.sc.statistics&&void 0!==this.sc.statistics&&this.sc.statistics.addTxText(n.byteLength)):e instanceof ArrayBuffer?(n=e,i=l.MESSAGE_TYPE_BYTE,null!==this.sc.statistics&&void 0!==this.sc.statistics&&this.sc.statistics.addTxBinary(n.byteLength)):null==e&&(n=new Uint8Array([]).buffer,i=l.MESSAGE_TYPE_EMPTY),null===n)return g("unknown data type"),!1;if(this._dcSendWithException(this.packMetadata(n.byteLength,i,t)),0<n.byteLength)try{return await this._dcSend(n,t)}catch(e){var a=this.taskManager.getTaskRequest(t);return null!==a&&(g(e),a.upload.dispatchEvent(new ErrorEvent("error",{error:e,message:"dcSend internal error"}))),this.onDataChannelError(e,t),!1}}))}async dcSendPause(e){return await this.dcSendWrapper(e,(async()=>(this._dcSendWithException(this.packMetadata(0,l.MESSAGE_TYPE_PAUSE_STOP,e)),!0)))}async dcSendResume(e){return await this.dcSendWrapper(e,(async()=>(this._dcSendWithException(this.packMetadata(0,l.MESSAGE_TYPE_PAUSE_CONTINUE,e)),!0)))}async dcSendEOF(e){return await this.dcSendWrapper(e,(async()=>(this._dcSendWithException(this.packMetadata(0,l.MESSAGE_TYPE_EOF,e)),!0)))}async dcSendEOU(e){return await this.dcSendWrapper(e,(async()=>(this._dcSendWithException(this.packMetadata(0,l.MESSAGE_TYPE_EOU,e)),!0)))}async dcTerminate(e){return await this.dcSendWrapper(e,(async()=>(this._dcSendWithException(this.packMetadata(0,l.MESSAGE_TYPE_TERMINATE,e)),!0)))}async _dcSend(e,t){var n=B.MAX_MSG_SIZE-1,s=e.byteLength,i=Math.floor(s/n),a=s%n;for(let s=1;s<=i;s++){if(await this._dcSendFragment(e.slice((s-1)*n,s*n),t))return!1}if(0!==a){if(await this._dcSendFragment(e.slice(i*n),t))return!1}return!0}async _dcSendFragment(e,t){return await this._dcSendFlowControl(e.byteLength),null===this.taskManager.getTaskRequest(t)?(this._dcSendWithException(new Uint8Array([B.ABORT_FLAG]).buffer),!0):(this._dcSendWithException(s.mergeArrayBufferList([new Uint8Array([1-B.ABORT_FLAG]).buffer,e])),!1)}_dcSendFlowControl(e){return this.dc.bufferedAmount+e>B.MAX_BUFFERED_AMOUNT?new Promise(((e,t)=>{this.dc.onbufferedamountlow=()=>{e()}})):new Promise(((e,t)=>{e()}))}_dcSendWithException(e){if(this.isDataChannelClose())throw DOMException.NETWORK_ERR;this.dc.send(e)}async _onDataChannelReceive(e){var t=this.semaphoreManager.getSempaphore("dcRecv");await t.start();var n=null,s=l.MESSAGE_TYPE_UNDEFINED,i=null;try{({data:n,type:s,taskId:i}=await this.dcRecv(e))}finally{t.end()}if(null!==n||l.MESSAGE_TYPE_HEADERS<=s&&s<l.MESSAGE_TYPE_UNDEFINED){var a=this.taskManager.getTaskRequest(i);if(null===a)return;switch(s){case l.MESSAGE_TYPE_STATUS:a.setStatusCode(n);break;case l.MESSAGE_TYPE_STATUSTEXT:a.setStatusText(n);break;case l.MESSAGE_TYPE_HEADERS:a.setResponseHeaders(n);break;case l.MESSAGE_TYPE_ERROR:this.onDataChannelError(n,i);break;case l.MESSAGE_TYPE_BYTE:case l.MESSAGE_TYPE_STRING:case l.MESSAGE_TYPE_EOF:this.onDataChannelReceive(n,s,i);break;case l.MESSAGE_TYPE_UPLOAD_PROGRESS:a.updateUploadProgress(n);break;default:g("unknown data channel message type",s)}}}async dcRecv(e){var t={data:null,type:l.MESSAGE_TYPE_UNDEFINED,taskId:null},n=e.data instanceof Blob?await e.data.arrayBuffer():e.data;if(l.MESSAGE_TYPE_UNDEFINED===this.recvType){var i=this.unpackMetadata(n);if(this.recvLen=i.length,this.recvType=i.type,this.recvTaskId=i.taskId,l.MESSAGE_TYPE_UNDEFINED===this.recvType)throw"Metadata Error"}else if(this.recvLen>this.recvTot){var a=new Uint8Array(n.slice(0,1))[0],r=n.slice(1);if(1===a)return this.resetDcRecv(),t;this.recvData.push(r),this.recvTot+=r.byteLength,l.MESSAGE_TYPE_BYTE!==this.recvType&&l.MESSAGE_TYPE_STRING!==this.recvType||this.onDataChannelChunk(r.byteLength,this.recvType,this.recvTaskId)}if(this.recvLen===this.recvTot){var o=s.mergeArrayBufferList(this.recvData);switch(this.recvType){case l.MESSAGE_TYPE_STRING:case l.MESSAGE_TYPE_HEADERS:case l.MESSAGE_TYPE_STATUS:case l.MESSAGE_TYPE_STATUSTEXT:case l.MESSAGE_TYPE_ERROR:t.data=s.textDecode(o),null!==this.sc.statistics&&void 0!==this.sc.statistics&&this.sc.statistics.addRxText(this.recvLen);break;case l.MESSAGE_TYPE_BYTE:t.data=o,null!==this.sc.statistics&&void 0!==this.sc.statistics&&this.sc.statistics.addRxBinary(this.recvLen);break;case l.MESSAGE_TYPE_UPLOAD_PROGRESS:var h=new DataView(o);t.data=Number(h.getBigUint64())}t.type=this.recvType,t.taskId=this.recvTaskId,this.resetDcRecv()}return t}resetDcRecv(){this.recvData=[],this.recvLen=0,this.recvTot=0,this.recvType=l.MESSAGE_TYPE_UNDEFINED,this.recvTaskId=0}packMetadata(e,t,n){var i=new Uint8Array(17),a=s.packUint64(e),r=new Uint8Array([t]),o=s.packUint64(n);return i.set(a),i.set(r,8),i.set(o,9),i.buffer}unpackMetadata(e){var t={};return t.length=s.unpackUint64(e.slice(0,8)),t.type=new Uint8Array(e.slice(8,9))[0],t.taskId=s.unpackUint64(e.slice(9,17)),t}}function G(e){e.endsWith(B.AUX_CHANNEL_POSTFIX)||(F.giveup(e),g(`give up channel ${e}`))}function Y(){let e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];var t=!0;return window._S&&(t=!window._S("isLogined")),q(B.DEFAULT_CHANNEL_NAME,t,!0,!e,!0)}function q(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],i=arguments.length>4&&void 0!==arguments[4]&&arguments[4];if(!0===s){if(F.isGiveup(e))return null;var a=F.get(e);return null==a||!F.inFailureCooldown(e)&&a.isConnectionFinished()?(q(e,t,n,!1,i),null):a||null}return new Promise(((s,a)=>{if(F.isGiveup(e))s(null);else{var r=()=>{F.registerEventCallbacks(e,{channelopen:()=>{let t=F.get(e);t?s(t):(g("[webrtc] error: channel open but the instance is null"),s(null))},channelclose:()=>{let t=F.get(e);null!=t&&!1===t.reconnect&&G(e)},signalerror:()=>{G(e),s(null)},timeout:()=>{let t=F.get(e);t&&t.reportStatus(!1,h.ERR_TYPE_TIMEOUT),s(null)}})},o=F.get(e);if(null==o||F.inFailureCooldown(e)||o.isConnectionFinished()){if(null!=o&&F.isMaxFailureCooldown(o.name))return G(e),void s(null);try{o=new B({name:e,sharing:t,aux:i,reconnect:n})}catch(t){return g("[webrtc] WebRTC construction failure",t),G(e),void s(null)}F.set(e,o),r()}else o.isDataChannelOpen()?s(o):r()}}))}e(B,"STUN_SERVER_ADDR","stun:checkip.webrtc.quickconnect."+(window.location.hostname.includes("quickconnect.to")?"to":"cn")),e(B,"AUX_CHANNEL_POSTFIX","@aux"),e(B,"DEFAULT_CHANNEL_NAME","Default"),e(B,"MAX_MSG_SIZE",65535),e(B,"MAX_BUFFERED_AMOUNT",8388608),e(B,"BUFFERED_AMOUNT_LOW_THRESHOLD",Math.floor(B.MAX_BUFFERED_AMOUNT/2)),e(B,"ABORT_FLAG",1),e(B,"PINGPONG_TIMEOUT",3e3),e(B,"PINGPONG_INTERVAL",5e3);class X{constructor(){const e=Math.floor(Math.random()*X.CACHE_BUSTING_MAX);this.swLauncher=null,this.swLauncherUrl=X.SW_SCOPE+"/"+X.SW_LAUNCHER+"?v="+e,this.disableSwDownload=!1,this.updateServiceWorker()}async updateServiceWorker(){if(!1===this.isSupport())return;const e=await u(this.swLauncherUrl);null!=e&&(e.onupdatefound=()=>{g("[webrtc] update download service worker"),this.swLauncher&&(this.removeIframe(this.swLauncher),this.swLauncher=null)},e.update())}isSupport(){return!0!==this.disableSwDownload&&(!d()&&!!(isSecureContext&&MessageChannel&&navigator.serviceWorker&&Headers&&Response&&WritableStream&&ReadableStream))}createWriteStream(e,t,n,s,i){this.loadSwLauncher(i);var a={downloadIframe:null,channel:new MessageChannel,pausableReqeust:e,errorCallback:s,fallbackCallback:i},r=t||this.getDownloadFileName(e,n);const o={};for(const[t,n]of e._getResponseHeadersObj(!0).entries())o[t]=n;var l={fileName:v(r),headers:o};return this.listenServiceWorker(a),this.sendContextToServiceWorker(l,a),this.getWriteStreamImplement(a)}getDownloadFileName(e,t){var n=null;const s=t.split("?")[0].split("/"),i=s.pop(),a=s.pop();if(void 0!==i&&""!==i?n=i:void 0!==a&&""!==a&&(n=a),null!==n)return n;throw"unable to get filename"}listenServiceWorker(e){e.channel.port1.onmessage=t=>{if(t.data.swRegisterError)return this.removeIframe(this.swLauncher),void this.handleSwLauncherFailure(e.fallbackCallback);const n=e.pausableReqeust;if(t.data.downloadUrl){const n=this.makeIframe(t.data.downloadUrl);e.downloadIframe=n,n.addEventListener("load",(()=>{const t=n.contentDocument.body;t&&t.firstChild&&(null!=t.firstChild.innerHTML?e.errorCallback(t.firstChild.innerHTML):e.fallbackCallback())}),{once:!0}),e.channel.port1.postMessage("startDownload")}else t.data.clearIframe?this.removeIframe(e.downloadIframe):t.data.pause?null!=n&&"function"==typeof n.pause&&n.pause():t.data.resume?null!=n&&"function"==typeof n.resume&&n.resume():t.data.abort&&(e.channel.port1.postMessage("abort"),null!=n&&"function"==typeof n.abort&&n.abort())}}sendContextToServiceWorker(e,t){const n=[e,"*",[t.channel.port2]];this.swLauncher.loaded?this.swLauncher.postMessage(...n):this.swLauncher.addEventListener("load",(()=>{this.swLauncher.postMessage(...n)}),{once:!0})}getWriteStreamImplement(e){return new window.WritableStream({write(t){if(!1==t instanceof Uint8Array)throw new TypeError("chunk is not Uint8Array");e.channel.port1.postMessage(t)},close(){e.channel.port1.postMessage("end")},abort(){e.channel.port1.postMessage("abort")}})}loadSwLauncher(e){if(null!==this.swLauncher)return;const t=new XMLHttpRequest;t.open("HEAD",this.swLauncherUrl),t.onload=()=>{200!==t.status&&this.handleSwLauncherFailure(e)},t.onerror=()=>{this.handleSwLauncherFailure(e)},t.send(),this.swLauncher=this.makeIframe(this.swLauncherUrl)}handleSwLauncherFailure(e){this.disableSwDownload=!0,e&&e(`fail to initialize ${X.SW_LAUNCHER}`)}makeIframe(e){if(!e)throw new Error("src is undefined");const t=document.createElement("iframe");return t.hidden=!0,t.src=e,t.loaded=!1,t.name="WebrtcDownloader",t.isIframe=!0,t.postMessage=function(){t.contentWindow.postMessage(...arguments)},t.addEventListener("load",(()=>{t.loaded=!0}),{once:!0}),document.body.appendChild(t),t}removeIframe(e){null!==e&&setTimeout((()=>{document.body.removeChild(e)}),X.IFRAME_REMOVE_DELAY)}}e(X,"SW_SCOPE","/scripts/synowebrtc/WebrtcDownloader"),e(X,"SW_LAUNCHER","swLauncher.html"),e(X,"IFRAME_REMOVE_DELAY",3e3),e(X,"CACHE_BUSTING_MAX",9999);const j=new X;var V={};return V.Cache={},V.GetDefaultChannel=Y,V.GetChannel=q,V.DownloadFile=function(e,t,n){var s=null,i=null,a=null,r={url:e.url||"",fileName:e.filename||null,method:e.method||"GET",params:e.params?{...e.params}:{},timeout:e.timeout||12e4,responseType:e.responseType||"json"};if(r.fileName){let e=new URL(r.url,location.href);e.pathname+=e.pathname.endsWith("/")?"":"/",e.pathname+=encodeURIComponent(r.fileName),r.url=e.href}for(let e of["api","method","version"])void 0===r.params[e]&&delete r.params[e];if(r.url+=r.url.includes("?")?"&":"?","GET"===r.method)r.url+=l();else{if("POST"!==r.method)throw"unsupported request method";{const e=r.params.SynoToken;null!=e&&(r.url+="SynoToken="+e,delete r.params.SynoToken)}}try{var o=Y(!1);if(null===o||!1===o.isDataChannelOpen())return void d();(s=o.newTaskRequest()).open(r.method,r.url),s.responseType="none",s.timeout=r.timeout,s.onReceiveHeaders=()=>{try{!function(){if(null!==i||null!==a)return;i=j.createWriteStream(s,r.fileName,r.url,(e=>{null!=t&&t(null,{data:h(e,r.responseType),status:s.status,statusText:s.statusText,headers:b(s.getAllResponseHeaders())})}),d),a=i.getWriter(),window.addEventListener("beforeunload",c)}()}catch(e){return void d(e)}},s.onMessage=(e,t,n)=>{a.write(new Uint8Array(e)).catch((e=>{s.abort()}))},s.onload=()=>{null!=a&&(a.close(),a=null),window.removeEventListener("beforeunload",c)},s.onError=d,s.ontimeout=d,"GET"===r.method?s.send().catch(d):s.send(l()).catch(d)}catch(e){d(e)}function l(){const e=[];for(let t of Object.entries(r.params))e.push(encodeURIComponent(t[0])+"="+encodeURIComponent(t[1]));return e.join("&")}function h(e,t){try{return"json"===t?JSON.parse(e):e}catch(e){return g(e),null}}function c(){s.abort(),a.abort()}function d(e){null!=s&&(s.abort(),s.onMessage=null),null!=e&&g("webrtc download fallback:",e),null!=n&&n()}},V.SetSynoWebAPI=function(e,t){if(null==e)throw"external synowebapi inst is null or undefined";r.call(this,e,t)},function(e){w(e,E)}(V),function(e){w(e,S)}(V.Cache),V.Cache.Flush=async()=>{await x.flushCache()},V.Cache.Unregister=async()=>{await x.unregisterServiceWorker()},Object.defineProperty(V,"IsRelay",{get:()=>{var e=window.location.hostname;return/.*[A-Za-z]{2,3}\d+\.quickconnect\.(to|cn)/.test(e)}}),Object.defineProperty(V,"SupportDownload",{get:()=>j.isSupport()}),r.call(V,window.synowebapi),V}();