From 764456edf0b72fd40fd64f79e59949a63a636005 Mon Sep 17 00:00:00 2001
From: zhangzengfei <zhangzengfei@smartai.com>
Date: 星期三, 22 九月 2021 17:15:30 +0800
Subject: [PATCH] 添加h265播放器

---
 src/components/wasmPlayer/wasm/player.js       |  182 +++++
 public/libs/wasmPlayer/libffmpeg.wasm          |    0 
 src/components/wasmPlayer/wasm/pcm-player.js   |  227 ++++++
 src/components/wasmPlayer/wasm/webgl.js        |  188 +++++
 public/libs/wasmPlayer/turbo.js                |  159 ++++
 src/components/wasmPlayer/wasm/img/bo1.png     |    0 
 src/components/wasmPlayer/index.vue            |  740 +++++++++++++++++++++
 src/components/wasmPlayer/wasm/index.html      |  143 ++++
 src/pages/cameraVideo/components/VideoItem.vue |   26 
 src/components/subComponents/ModelCard.vue     |  346 +++++++---
 public/libs/wasmPlayer/libffmpeg.js            |    1 
 11 files changed, 1,897 insertions(+), 115 deletions(-)

diff --git a/public/libs/wasmPlayer/libffmpeg.js b/public/libs/wasmPlayer/libffmpeg.js
new file mode 100644
index 0000000..19d0d1a
--- /dev/null
+++ b/public/libs/wasmPlayer/libffmpeg.js
@@ -0,0 +1 @@
+var Module=typeof Module!=="undefined"?Module:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}function convertJsFunctionToWasm(func,sig){if(typeof WebAssembly.Function==="function"){var typeNames={"i":"i32","j":"i64","f":"f32","d":"f64"};var type={parameters:[],results:sig[0]=="v"?[]:[typeNames[sig[0]]]};for(var i=1;i<sig.length;++i){type.parameters.push(typeNames[sig[i]])}return new WebAssembly.Function(type,func)}var typeSection=[1,0,1,96];var sigRet=sig.slice(0,1);var sigParam=sig.slice(1);var typeCodes={"i":127,"j":126,"f":125,"d":124};typeSection.push(sigParam.length);for(var i=0;i<sigParam.length;++i){typeSection.push(typeCodes[sigParam[i]])}if(sigRet=="v"){typeSection.push(0)}else{typeSection=typeSection.concat([1,typeCodes[sigRet]])}typeSection[1]=typeSection.length-2;var bytes=new Uint8Array([0,97,115,109,1,0,0,0].concat(typeSection,[2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0]));var module=new WebAssembly.Module(bytes);var instance=new WebAssembly.Instance(module,{"e":{"f":func}});var wrappedFunc=instance.exports["f"];return wrappedFunc}var freeTableIndexes=[];var functionsInTableMap;function addFunctionWasm(func,sig){var table=wasmTable;if(!functionsInTableMap){functionsInTableMap=new WeakMap;for(var i=0;i<table.length;i++){var item=table.get(i);if(item){functionsInTableMap.set(item,i)}}}if(functionsInTableMap.has(func)){return functionsInTableMap.get(func)}var ret;if(freeTableIndexes.length){ret=freeTableIndexes.pop()}else{ret=table.length;try{table.grow(1)}catch(err){if(!(err instanceof RangeError)){throw err}throw"Unable to grow wasm table. Set ALLOW_TABLE_GROWTH."}}try{table.set(ret,func)}catch(err){if(!(err instanceof TypeError)){throw err}var wrapped=convertJsFunctionToWasm(func,sig);table.set(ret,wrapped)}functionsInTableMap.set(func,ret);return ret}function addFunction(func,sig){return addFunctionWasm(func,sig)}var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var wasmTable;var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx<endPtr){var u0=heap[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heap[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heap[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heap[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i<str.length;++i){HEAP8[buffer++>>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var WASM_PAGE_SIZE=65536;var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_INITIAL_MEMORY=Module["INITIAL_MEMORY"]||268435456;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_INITIAL_MEMORY/WASM_PAGE_SIZE,"maximum":INITIAL_INITIAL_MEMORY/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_INITIAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="libffmpeg.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return Promise.resolve().then(getBinary)}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmTable=Module["asm"]["O"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}var tempDouble;var tempI64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function demangle(func){return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function jsStackTrace(){var error=new Error;if(!error.stack){try{throw new Error}catch(e){error=e}if(!error.stack){return"(no stack trace available)"}}return error.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}function ___assert_fail(condition,filename,line,func){abort("Assertion failed: "+UTF8ToString(condition)+", at: "+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=function(){var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else if(typeof dateNow!=="undefined"){_emscripten_get_now=dateNow}else _emscripten_get_now=function(){return performance.now()};var _emscripten_get_now_is_monotonic=true;function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}function _clock_gettime(clk_id,tp){var now;if(clk_id===0){now=Date.now()}else if((clk_id===1||clk_id===4)&&_emscripten_get_now_is_monotonic){now=_emscripten_get_now()}else{setErrNo(28);return-1}HEAP32[tp>>2]=now/1e3|0;HEAP32[tp+4>>2]=now%1e3*1e3*1e3|0;return 0}function ___clock_gettime(a0,a1){return _clock_gettime(a0,a1)}function _tzset(){if(_tzset.called)return;_tzset.called=true;HEAP32[__get_timezone()>>2]=(new Date).getTimezoneOffset()*60;var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);HEAP32[__get_daylight()>>2]=Number(winter.getTimezoneOffset()!=summer.getTimezoneOffset());function extractZone(date){var match=date.toTimeString().match(/\(([A-Za-z ]+)\)$/);return match?match[1]:"GMT"}var winterName=extractZone(winter);var summerName=extractZone(summer);var winterNamePtr=allocateUTF8(winterName);var summerNamePtr=allocateUTF8(summerName);if(summer.getTimezoneOffset()<winter.getTimezoneOffset()){HEAP32[__get_tzname()>>2]=winterNamePtr;HEAP32[__get_tzname()+4>>2]=summerNamePtr}else{HEAP32[__get_tzname()>>2]=summerNamePtr;HEAP32[__get_tzname()+4>>2]=winterNamePtr}}function _localtime_r(time,tmPtr){_tzset();var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var start=new Date(date.getFullYear(),0,1);var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst;var zonePtr=HEAP32[__get_tzname()+(dst?4:0)>>2];HEAP32[tmPtr+40>>2]=zonePtr;return tmPtr}function ___localtime_r(a0,a1){return _localtime_r(a0,a1)}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start<arr.length;start++){if(arr[start]!=="")break}var end=arr.length-1;for(;end>=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i<length;i++){if(fromParts[i]!==toParts[i]){samePartsLength=i;break}}var outputParts=[];for(var i=samePartsLength;i<fromParts.length;i++){outputParts.push("..")}outputParts=outputParts.concat(toParts.slice(samePartsLength));return outputParts.join("/")}};var TTY={ttys:[],init:function(){},shutdown:function(){},register:function(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open:function(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close:function(stream){stream.tty.ops.flush(stream.tty)},flush:function(stream){stream.tty.ops.flush(stream.tty)},read:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i<length;i++){var result;try{result=stream.tty.ops.get_char(stream.tty)}catch(e){throw new FS.ErrnoError(29)}if(result===undefined&&bytesRead===0){throw new FS.ErrnoError(6)}if(result===null||result===undefined)break;bytesRead++;buffer[offset+i]=result}if(bytesRead){stream.node.timestamp=Date.now()}return bytesRead},write:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.put_char){throw new FS.ErrnoError(60)}try{for(var i=0;i<length;i++){stream.tty.ops.put_char(stream.tty,buffer[offset+i])}}catch(e){throw new FS.ErrnoError(29)}if(length){stream.node.timestamp=Date.now()}return i}},default_tty_ops:{get_char:function(tty){if(!tty.input.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc?Buffer.alloc(BUFSIZE):new Buffer(BUFSIZE);var bytesRead=0;try{bytesRead=nodeFS.readSync(process.stdin.fd,buf,0,BUFSIZE,null)}catch(e){if(e.toString().indexOf("EOF")!=-1)bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){var alignedSize=alignMemory(size,16384);var ptr=_malloc(alignedSize);while(size<alignedSize)HEAP8[ptr+size++]=0;return ptr}var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node}return node},getFileDataAsRegularArray:function(node){if(node.contents&&node.contents.subarray){var arr=[];for(var i=0;i<node.usedBytes;++i)arr.push(node.contents[i]);return arr}return node.contents},getFileDataAsTypedArray:function(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage:function(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity<CAPACITY_DOUBLING_MAX?2:1.125)>>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length<newSize)node.contents.push(0);node.usedBytes=newSize},node_ops:{getattr:function(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr:function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup:function(parent,name){throw FS.genericErrors[44]},mknod:function(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename:function(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.name=new_name;new_dir.contents[new_name]=old_node;old_node.parent=new_dir},unlink:function(parent,name){delete parent.contents[name]},rmdir:function(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name]},readdir:function(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink:function(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink:function(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read:function(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i<size;i++)buffer[offset+i]=contents[position+i]}return size},write:function(stream,buffer,offset,length,position,canOwn){if(!length)return 0;var node=stream.node;node.timestamp=Date.now();if(buffer.subarray&&(!node.contents||node.contents.subarray)){if(canOwn){node.contents=buffer.subarray(offset,offset+length);node.usedBytes=length;return length}else if(node.usedBytes===0&&position===0){node.contents=buffer.slice(offset,offset+length);node.usedBytes=length;return length}else if(position+length<=node.usedBytes){node.contents.set(buffer.subarray(offset,offset+length),position);return length}}MEMFS.expandFileStorage(node,position+length);if(node.contents.subarray&&buffer.subarray){node.contents.set(buffer.subarray(offset,offset+length),position)}else{for(var i=0;i<length;i++){node.contents[position+i]=buffer[offset+i]}}node.usedBytes=Math.max(node.usedBytes,position+length);return length},llseek:function(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){position+=stream.node.usedBytes}}if(position<0){throw new FS.ErrnoError(28)}return position},allocate:function(stream,offset,length){MEMFS.expandFileStorage(stream.node,offset+length);stream.node.usedBytes=Math.max(stream.node.usedBytes,offset+length)},mmap:function(stream,address,length,position,prot,flags){assert(address===0);if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr;var allocated;var contents=stream.node.contents;if(!(flags&2)&&contents.buffer===buffer){allocated=false;ptr=contents.byteOffset}else{if(position>0||position+length<contents.length){if(contents.subarray){contents=contents.subarray(position,position+length)}else{contents=Array.prototype.slice.call(contents,position,position+length)}}allocated=true;ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}HEAP8.set(contents,ptr)}return{ptr:ptr,allocated:allocated}},msync:function(stream,buffer,offset,length,mmapFlags){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(mmapFlags&2){return 0}var bytesWritten=MEMFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,handleFSError:function(e){if(!(e instanceof FS.ErrnoError))throw e+" : "+stackTrace();return setErrNo(e.errno)},lookupPath:function(path,opts){path=PATH_FS.resolve(FS.cwd(),path);opts=opts||{};if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};for(var key in defaults){if(opts[key]===undefined){opts[key]=defaults[key]}}if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i<parts.length;i++){var islast=i===parts.length-1;if(islast&&opts.parent){break}current=FS.lookupNode(current,parts[i]);current_path=PATH.join2(current_path,parts[i]);if(FS.isMountpoint(current)){if(!islast||islast&&opts.follow_mount){current=current.mounted.root}}if(!islast||opts.follow){var count=0;while(FS.isLink(current.mode)){var link=FS.readlink(current_path);current_path=PATH_FS.resolve(PATH.dirname(current_path),link);var lookup=FS.lookupPath(current_path,{recurse_count:opts.recurse_count});current=lookup.node;if(count++>40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i<name.length;i++){hash=(hash<<5)-hash+name.charCodeAt(i)|0}return(parentid+hash>>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;i<dirs.length;++i){if(!dirs[i])continue;d+="/"+dirs[i];try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev:function(path,mode,dev){if(typeof dev==="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink:function(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename:function(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}try{if(FS.trackingDelegate["willMovePath"]){FS.trackingDelegate["willMovePath"](old_path,new_path)}}catch(e){err("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}try{if(FS.trackingDelegate["onMovePath"])FS.trackingDelegate["onMovePath"](old_path,new_path)}catch(e){err("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}},rmdir:function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}},readdir:function(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(54)}return node.node_ops.readdir(node)},unlink:function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.unlink(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}},readlink:function(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return PATH_FS.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))},stat:function(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(44)}if(!node.node_ops.getattr){throw new FS.ErrnoError(63)}return node.node_ops.getattr(node)},lstat:function(path){return FS.stat(path,true)},chmod:function(path,mode,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})},lchmod:function(path,mode){FS.chmod(path,mode,true)},fchmod:function(fd,mode){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chmod(stream.node,mode)},chown:function(path,uid,gid,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{timestamp:Date.now()})},lchown:function(path,uid,gid){FS.chown(path,uid,gid,true)},fchown:function(fd,uid,gid){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chown(stream.node,uid,gid)},truncate:function(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})},ftruncate:function(fd,len){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.truncate(stream.node,len)},utime:function(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})},open:function(path,flags,mode,fd_start,fd_end){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags==="string"?FS.modeStringToFlags(flags):flags;mode=typeof mode==="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path==="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false},fd_start,fd_end);if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1;err("FS.trackingDelegate error on read file: "+path)}}try{if(FS.trackingDelegate["onOpenFile"]){var trackingFlags=0;if((flags&2097155)!==1){trackingFlags|=FS.tracking.openFlags.READ}if((flags&2097155)!==0){trackingFlags|=FS.tracking.openFlags.WRITE}FS.trackingDelegate["onOpenFile"](path,trackingFlags)}}catch(e){err("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: "+e.message)}return stream},close:function(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed:function(stream){return stream.fd===null},llseek:function(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read:function(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!=="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write:function(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!=="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;try{if(stream.path&&FS.trackingDelegate["onWriteToFile"])FS.trackingDelegate["onWriteToFile"](stream.path)}catch(e){err("FS.trackingDelegate['onWriteToFile']('"+stream.path+"') threw an exception: "+e.message)}return bytesWritten},allocate:function(stream,offset,length){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap:function(stream,address,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,address,length,position,prot,flags)},msync:function(stream,buffer,offset,length,mmapFlags){if(!stream||!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:function(stream){return 0},ioctl:function(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile:function(path,opts){opts=opts||{};opts.flags=opts.flags||"r";opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error('Invalid encoding type "'+opts.encoding+'"')}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile:function(path,data,opts){opts=opts||{};opts.flags=opts.flags||"w";var stream=FS.open(path,opts.flags,opts.mode);if(typeof data==="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:function(){return FS.currentPath},chdir:function(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories:function(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices:function(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:function(){return 0},write:function(stream,buffer,offset,length,pos){return length}});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var random_device=getRandomDevice();FS.createDevice("/dev","random",random_device);FS.createDevice("/dev","urandom",random_device);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories:function(){FS.mkdir("/proc");FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:function(){var node=FS.createNode("/proc/self","fd",16384|511,73);node.node_ops={lookup:function(parent,name){var fd=+name;var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:function(){return stream.path}}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams:function(){if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin","r");var stdout=FS.open("/dev/stdout","w");var stderr=FS.open("/dev/stderr","w")},ensureErrnoError:function(){if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.node=node;this.setErrno=function(errno){this.errno=errno};this.setErrno(errno);this.message="FS error"};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach(function(code){FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack="<generic error, no stack>"})},staticInit:function(){FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS}},init:function(input,output,error){FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:function(){FS.init.initialized=false;var fflush=Module["_fflush"];if(fflush)fflush(0);for(var i=0;i<FS.streams.length;i++){var stream=FS.streams[i];if(!stream){continue}FS.close(stream)}},getMode:function(canRead,canWrite){var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode},findObject:function(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(ret.exists){return ret.object}else{setErrNo(ret.error);return null}},analyzePath:function(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath:function(parent,path,canRead,canWrite){parent=typeof parent==="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current},createFile:function(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile:function(parent,name,data,canRead,canWrite,canOwn){var path=name?PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name):parent;var mode=FS.getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data==="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i<len;++i)arr[i]=data.charCodeAt(i);data=arr}FS.chmod(node,mode|146);var stream=FS.open(node,"w");FS.write(stream,data,0,data.length,0,canOwn);FS.close(stream);FS.chmod(node,mode)}return node},createDevice:function(parent,name,input,output){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:function(stream){stream.seekable=false},close:function(stream){if(output&&output.buffer&&output.buffer.length){output(10)}},read:function(stream,buffer,offset,length,pos){var bytesRead=0;for(var i=0;i<length;i++){var result;try{result=input()}catch(e){throw new FS.ErrnoError(29)}if(result===undefined&&bytesRead===0){throw new FS.ErrnoError(6)}if(result===null||result===undefined)break;bytesRead++;buffer[offset+i]=result}if(bytesRead){stream.node.timestamp=Date.now()}return bytesRead},write:function(stream,buffer,offset,length,pos){for(var i=0;i<length;i++){try{output(buffer[offset+i])}catch(e){throw new FS.ErrnoError(29)}}if(length){stream.node.timestamp=Date.now()}return i}});return FS.mkdev(path,mode,dev)},forceLoadFile:function(obj){if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;var success=true;if(typeof XMLHttpRequest!=="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(read_){try{obj.contents=intArrayFromString(read_(obj.url),true);obj.usedBytes=obj.contents.length}catch(e){success=false}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}if(!success)setErrNo(29);return success},createLazyFile:function(parent,name,url,canRead,canWrite){function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i<size;i++){buffer[offset+i]=contents[position+i]}}else{for(var i=0;i<size;i++){buffer[offset+i]=contents.get(position+i)}}return size};node.stream_ops=stream_ops;return node},createPreloadedFile:function(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish){Browser.init();var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency("cp "+fullname);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}var handled=false;Module["preloadPlugins"].forEach(function(plugin){if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,function(){if(onerror)onerror();removeRunDependency(dep)});handled=true}});if(!handled)finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){Browser.asyncLoad(url,function(byteArray){processData(byteArray)},onerror)}else{processData(url)}},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},DB_NAME:function(){return"EM_FS_"+window.location.pathname},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function(paths,onload,onerror){onload=onload||function(){};onerror=onerror||function(){};var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=function openRequest_onupgradeneeded(){out("creating db");var db=openRequest.result;db.createObjectStore(FS.DB_STORE_NAME)};openRequest.onsuccess=function openRequest_onsuccess(){var db=openRequest.result;var transaction=db.transaction([FS.DB_STORE_NAME],"readwrite");var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(function(path){var putRequest=files.put(FS.analyzePath(path).object.contents,path);putRequest.onsuccess=function putRequest_onsuccess(){ok++;if(ok+fail==total)finish()};putRequest.onerror=function putRequest_onerror(){fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror},loadFilesFromDB:function(paths,onload,onerror){onload=onload||function(){};onerror=onerror||function(){};var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=onerror;openRequest.onsuccess=function openRequest_onsuccess(){var db=openRequest.result;try{var transaction=db.transaction([FS.DB_STORE_NAME],"readonly")}catch(e){onerror(e);return}var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(function(path){var getRequest=files.get(path);getRequest.onsuccess=function getRequest_onsuccess(){if(FS.analyzePath(path).exists){FS.unlink(path)}FS.createDataFile(PATH.dirname(path),PATH.basename(path),getRequest.result,true,true,true);ok++;if(ok+fail==total)finish()};getRequest.onerror=function getRequest_onerror(){fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror}};var SYSCALLS={mappings:{},DEFAULT_POLLMASK:5,umask:511,calculateAt:function(dirfd,path){if(path[0]!=="/"){var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=FS.getStream(dirfd);if(!dirstream)throw new FS.ErrnoError(8);dir=dirstream.path}path=PATH.join2(dir,path)}return path},doStat:function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov+i*8>>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr<len)break}return ret},doWritev:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov+i*8>>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function ___sys_access(path,amode){try{path=SYSCALLS.getStr(path);return SYSCALLS.doAccess(path,amode)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_fstat64(fd,buf){try{var stream=SYSCALLS.getStreamFromFD(fd);return SYSCALLS.doStat(FS.stat,stream.path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_getdents64(fd,dirp,count){try{var stream=SYSCALLS.getStreamFromFD(fd);if(!stream.getdents){stream.getdents=FS.readdir(stream.path)}var struct_size=280;var pos=0;var off=FS.llseek(stream,0,1);var idx=Math.floor(off/struct_size);while(idx<stream.getdents.length&&pos+struct_size<=count){var id;var type;var name=stream.getdents[idx];if(name[0]==="."){id=1;type=4}else{var child=FS.lookupNode(stream.node,name);id=child.id;type=FS.isChrdev(child.mode)?2:FS.isDir(child.mode)?4:FS.isLink(child.mode)?10:8}tempI64=[id>>>0,(tempDouble=id,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos>>2]=tempI64[0],HEAP32[dirp+pos+4>>2]=tempI64[1];tempI64=[(idx+1)*struct_size>>>0,(tempDouble=(idx+1)*struct_size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos+8>>2]=tempI64[0],HEAP32[dirp+pos+12>>2]=tempI64[1];HEAP16[dirp+pos+16>>1]=280;HEAP8[dirp+pos+18>>0]=type;stringToUTF8(name,dirp+pos+19,256);pos+=struct_size;idx+=1}FS.llseek(stream,idx*struct_size,0);return pos}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_lstat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.lstat,path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_mkdir(path,mode){try{path=SYSCALLS.getStr(path);return SYSCALLS.doMkdir(path,mode)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=SYSCALLS.get();var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_read(fd,buf,count){try{var stream=SYSCALLS.getStreamFromFD(fd);return FS.read(stream,HEAP8,buf,count)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_rename(old_path,new_path){try{old_path=SYSCALLS.getStr(old_path);new_path=SYSCALLS.getStr(new_path);FS.rename(old_path,new_path);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_rmdir(path){try{path=SYSCALLS.getStr(path);FS.rmdir(path);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_unlink(path){try{path=SYSCALLS.getStr(path);FS.unlink(path);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function _abort(){abort()}function _clock(){if(_clock.start===undefined)_clock.start=Date.now();return(Date.now()-_clock.start)*(1e6/1e3)|0}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function abortOnCannotGrowMemory(requestedSize){abort("OOM")}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;abortOnCannotGrowMemory(requestedSize)}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}function _exit(status){exit(status)}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_fdstat_get(fd,pbuf){try{var stream=SYSCALLS.getStreamFromFD(fd);var type=stream.tty?2:FS.isDir(stream.mode)?3:FS.isLink(stream.mode)?7:4;HEAP8[pbuf>>0]=type;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _gettimeofday(ptr){var now=Date.now();HEAP32[ptr>>2]=now/1e3|0;HEAP32[ptr+4>>2]=now%1e3*1e3|0;return 0}function _gmtime_r(time,tmPtr){var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getUTCSeconds();HEAP32[tmPtr+4>>2]=date.getUTCMinutes();HEAP32[tmPtr+8>>2]=date.getUTCHours();HEAP32[tmPtr+12>>2]=date.getUTCDate();HEAP32[tmPtr+16>>2]=date.getUTCMonth();HEAP32[tmPtr+20>>2]=date.getUTCFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getUTCDay();HEAP32[tmPtr+36>>2]=0;HEAP32[tmPtr+32>>2]=0;var start=Date.UTC(date.getUTCFullYear(),0,1,0,0,0,0);var yday=(date.getTime()-start)/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;if(!_gmtime_r.GMTString)_gmtime_r.GMTString=allocateUTF8("GMT");HEAP32[tmPtr+40>>2]=_gmtime_r.GMTString;return tmPtr}function _mktime(tmPtr){_tzset();var date=new Date(HEAP32[tmPtr+20>>2]+1900,HEAP32[tmPtr+16>>2],HEAP32[tmPtr+12>>2],HEAP32[tmPtr+8>>2],HEAP32[tmPtr+4>>2],HEAP32[tmPtr>>2],0);var dst=HEAP32[tmPtr+32>>2];var guessedOffset=date.getTimezoneOffset();var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dstOffset=Math.min(winterOffset,summerOffset);if(dst<0){HEAP32[tmPtr+32>>2]=Number(summerOffset!=winterOffset&&dstOffset==guessedOffset)}else if(dst>0!=(dstOffset==guessedOffset)){var nonDstOffset=Math.max(winterOffset,summerOffset);var trueOffset=dst>0?dstOffset:nonDstOffset;date.setTime(date.getTime()+(trueOffset-guessedOffset)*6e4)}HEAP32[tmPtr+24>>2]=date.getDay();var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;return date.getTime()/1e3|0}function _usleep(useconds){var start=_emscripten_get_now();while(_emscripten_get_now()-start<useconds/1e3){}}function _nanosleep(rqtp,rmtp){if(rqtp===0){setErrNo(28);return-1}var seconds=HEAP32[rqtp>>2];var nanoseconds=HEAP32[rqtp+4>>2];if(nanoseconds<0||nanoseconds>999999999||seconds<0){setErrNo(28);return-1}if(rmtp!==0){HEAP32[rmtp>>2]=0;HEAP32[rmtp+4>>2]=0}return _usleep(seconds*1e6+nanoseconds/1e3)}function _pthread_create(){return 6}function _pthread_join(){}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value==="number"?value.toString():value||"";while(str.length<digits){str=character[0]+str}return str}function leadingNulls(value,digits){return leadingSomething(value,digits,"0")}function compareByDay(date1,date2){function sgn(value){return value<0?-1:value>0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var janFirst=new Date(date.tm_year+1900,0,1);var firstSunday=janFirst.getDay()===0?janFirst:__addDays(janFirst,7-janFirst.getDay());var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstSunday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstSundayUntilEndJanuary=31-firstSunday.getDate();var days=firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstSunday,janFirst)===0?"01":"00"},"%V":function(date){var janFourthThisYear=new Date(date.tm_year+1900,0,4);var janFourthNextYear=new Date(date.tm_year+1901,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);var endDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);if(compareByDay(endDate,firstWeekStartThisYear)<0){return"53"}if(compareByDay(firstWeekStartNextYear,endDate)<=0){return"01"}var daysDifference;if(firstWeekStartThisYear.getFullYear()<date.tm_year+1900){daysDifference=date.tm_yday+32-firstWeekStartThisYear.getDate()}else{daysDifference=date.tm_yday+1-firstWeekStartThisYear.getDate()}return leadingNulls(Math.ceil(daysDifference/7),2)},"%w":function(date){return date.tm_wday},"%W":function(date){var janFirst=new Date(date.tm_year,0,1);var firstMonday=janFirst.getDay()===1?janFirst:__addDays(janFirst,janFirst.getDay()===0?1:7-janFirst.getDay()+1);var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstMonday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstMondayUntilEndJanuary=31-firstMonday.getDate();var days=firstMondayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstMonday,janFirst)===0?"01":"00"},"%y":function(date){return(date.tm_year+1900).toString().substring(2)},"%Y":function(date){return date.tm_year+1900},"%z":function(date){var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};for(var rule in EXPANSION_RULES_2){if(pattern.indexOf(rule)>=0){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _sysconf(name){switch(name){case 30:return 16384;case 85:var maxHeapSize=HEAPU8.length;return maxHeapSize/16384;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:case 79:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}setErrNo(28);return-1}function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;Module["FS_unlink"]=FS.unlink;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}__ATINIT__.push({func:function(){___wasm_call_ctors()}});var asmLibraryArg={"g":___assert_fail,"y":___clock_gettime,"w":___localtime_r,"J":___sys_access,"l":___sys_fcntl64,"D":___sys_fstat64,"x":___sys_getdents64,"B":___sys_ioctl,"F":___sys_lstat64,"E":___sys_mkdir,"p":___sys_open,"G":___sys_read,"C":___sys_rename,"H":___sys_rmdir,"o":___sys_stat64,"I":___sys_unlink,"b":_abort,"L":_clock,"h":_clock_gettime,"s":_emscripten_memcpy_big,"t":_emscripten_resize_heap,"u":_environ_get,"v":_environ_sizes_get,"N":_exit,"k":_fd_close,"q":_fd_fdstat_get,"z":_fd_read,"r":_fd_seek,"m":_fd_write,"A":_gettimeofday,"d":_gmtime_r,"f":_localtime_r,"a":wasmMemory,"n":_mktime,"K":_nanosleep,"j":_pthread_create,"i":_pthread_join,"c":_strftime,"M":_sysconf,"e":_time};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["P"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["Q"]).apply(null,arguments)};var _Initialize=Module["_Initialize"]=function(){return(_Initialize=Module["_Initialize"]=Module["asm"]["R"]).apply(null,arguments)};var _Play=Module["_Play"]=function(){return(_Play=Module["_Play"]=Module["asm"]["S"]).apply(null,arguments)};var _Pause=Module["_Pause"]=function(){return(_Pause=Module["_Pause"]=Module["asm"]["T"]).apply(null,arguments)};var _Resume=Module["_Resume"]=function(){return(_Resume=Module["_Resume"]=Module["asm"]["U"]).apply(null,arguments)};var _Seek=Module["_Seek"]=function(){return(_Seek=Module["_Seek"]=Module["asm"]["V"]).apply(null,arguments)};var _Stop=Module["_Stop"]=function(){return(_Stop=Module["_Stop"]=Module["asm"]["W"]).apply(null,arguments)};var _UnInitialize=Module["_UnInitialize"]=function(){return(_UnInitialize=Module["_UnInitialize"]=Module["asm"]["X"]).apply(null,arguments)};var _Turbo0=Module["_Turbo0"]=function(){return(_Turbo0=Module["_Turbo0"]=Module["asm"]["Y"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["Z"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["_"]).apply(null,arguments)};var __get_tzname=Module["__get_tzname"]=function(){return(__get_tzname=Module["__get_tzname"]=Module["asm"]["$"]).apply(null,arguments)};var __get_daylight=Module["__get_daylight"]=function(){return(__get_daylight=Module["__get_daylight"]=Module["asm"]["aa"]).apply(null,arguments)};var __get_timezone=Module["__get_timezone"]=function(){return(__get_timezone=Module["__get_timezone"]=Module["asm"]["ba"]).apply(null,arguments)};Module["addRunDependency"]=addRunDependency;Module["removeRunDependency"]=removeRunDependency;Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;Module["FS_unlink"]=FS.unlink;Module["addFunction"]=addFunction;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){if(implicit&&noExitRuntime&&status===0){return}if(noExitRuntime){}else{EXITSTATUS=status;exitRuntime();if(Module["onExit"])Module["onExit"](status);ABORT=true}quit_(status,new ExitStatus(status))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run();
diff --git a/public/libs/wasmPlayer/libffmpeg.wasm b/public/libs/wasmPlayer/libffmpeg.wasm
new file mode 100644
index 0000000..1c0cf0e
--- /dev/null
+++ b/public/libs/wasmPlayer/libffmpeg.wasm
Binary files differ
diff --git a/public/libs/wasmPlayer/turbo.js b/public/libs/wasmPlayer/turbo.js
new file mode 100644
index 0000000..443331f
--- /dev/null
+++ b/public/libs/wasmPlayer/turbo.js
@@ -0,0 +1,159 @@
+Module = {
+  onRuntimeInitialized: function() {
+    onWasmLoaded()
+  },
+}
+importScripts('libffmpeg.js')
+
+var MediaName = null
+var IsStream = true
+var FileLen = -1
+
+var SocketObj //WebSocket
+var CPointer_Buffer = null
+var CPointer_Cap = 0
+
+function onWasmLoaded() {
+  DeliverVideo = Module.addFunction(function(Buf, BufLen, TimeStamp) {
+    var CPointer_Array = Module.HEAPU8.subarray(Buf, Buf + BufLen)
+    var message = {
+      command: 'deliver_video',
+      sample: { time_stamp: TimeStamp, buf: new Uint8Array(CPointer_Array) },
+    }
+    self.postMessage(message, [message.sample.buf.buffer])
+  }, 'viii')
+
+  DeliverAudio = Module.addFunction(function(Buf, BufLen, TimeStamp) {
+    var CPointer_Array = Module.HEAPU8.subarray(Buf, Buf + BufLen)
+    var message = {
+      command: 'deliver_audio',
+      sample: { time_stamp: TimeStamp, buf: new Uint8Array(CPointer_Array) },
+    }
+    self.postMessage(message, [message.sample.buf.buffer])
+  }, 'viii')
+
+  GetFileLength = Module.addFunction(function() {
+    if (FileLen == -1) {
+      var xhr = new XMLHttpRequest()
+      xhr.open('get', MediaName, false) //false: syn mode
+      xhr.send()
+      FileLen = xhr.getResponseHeader('Content-Length')
+      xhr.abort()
+    }
+    return FileLen
+  }, 'i')
+
+  ReadFile = Module.addFunction(function(Buf, Pos, Size) {
+    var xhr = new XMLHttpRequest()
+    xhr.open('get', MediaName, false)
+    xhr.responseType = 'arraybuffer'
+    xhr.setRequestHeader('Range', 'bytes=' + Pos + '-' + (Pos + Size - 1))
+    xhr.send()
+    Module.HEAPU8.set(new Uint8Array(xhr.response), Buf) //Uint8Array(xhr.response).length
+    xhr.abort()
+  }, 'viii')
+
+  CreateVideo = Module.addFunction(function(Duration, Width, Height) {
+    self.postMessage({
+      command: 'create_video',
+      param: { duration: Duration, width: Width, height: Height },
+    })
+  }, 'viii')
+
+  CreateAudio = Module.addFunction(function(Channel, SampleRate) {
+    self.postMessage({
+      command: 'create_audio',
+      param: { channel: Channel, sample_rate: SampleRate },
+    })
+  }, 'vii')
+
+  Module._Initialize(
+    DeliverVideo,
+    DeliverAudio,
+    GetFileLength,
+    ReadFile,
+    CreateVideo,
+    CreateAudio
+  )
+  self.postMessage({ command: 'initialized' })
+}
+
+function OnTimer() {
+  Module._Turbo0(null, 0)
+}
+
+function requestWebsocket(url, msg, cb_message) {
+  SocketObj = new WebSocket(url)
+  SocketObj.binaryType = 'arraybuffer'
+  SocketObj.onopen = function(evt) {
+    SocketObj.send(msg)
+  }
+  SocketObj.onerror = function(evt) {
+    console.log('Ws connect error ' + evt.data)
+  }
+  SocketObj.onmessage = cb_message
+  SocketObj.onclose = function() {
+    console.log('Ws closed.')
+  }
+}
+
+function downloadFileByWebsocket(ws, payload) {
+  this.requestWebsocket(ws, payload, function(evt) {
+    if (evt.data.byteLength > CPointer_Cap) {
+      if (CPointer_Buffer != null) Module._free(CPointer_Buffer)
+      CPointer_Cap = evt.data.byteLength
+      CPointer_Buffer = Module._malloc(CPointer_Cap)
+    }
+
+    var typedArray = new Uint8Array(evt.data)
+    Module.HEAPU8.set(typedArray, CPointer_Buffer)
+    //console.log("websocket data: "+typedArray.length);
+    Module._Turbo0(CPointer_Buffer, typedArray.length)
+  })
+}
+
+self.onmessage = function(evt) {
+  switch (evt.data.command) {
+    case 'play': {
+      MediaName = evt.data.media_name
+      IsStream = evt.data.other
+      if (IsStream) {
+        downloadFileByWebsocket(MediaName, evt.data.payload)
+      }
+
+      Module._Play(null, !IsStream)
+      TimerID = setInterval(OnTimer, 5) //姝ゅ�艰秺灏�,娓叉煋绮惧害瓒婇珮,涓斿彲澧炲己'鍙岀嚎绋嬬紦鍐插钩婊戞満鍒�'鍙潬鎬�
+      break
+    }
+    case 'pause': {
+      Module._Pause()
+      clearInterval(TimerID)
+      break
+    }
+    case 'resume': {
+      Module._Resume()
+      TimerID = setInterval(OnTimer, 5)
+      break
+    }
+    case 'stop': {
+      Module._Stop()
+      clearInterval(TimerID)
+      if (IsStream) {
+        SocketObj.close()
+        if (CPointer_Buffer != null) {
+          Module._free(CPointer_Buffer)
+          CPointer_Buffer = null
+          CPointer_Cap = 0
+        }
+      }
+      close() //exit worker
+      break
+    }
+    case 'seek': {
+      Module._Seek(evt.data.pos)
+      break
+    }
+    default:
+      return
+  }
+}
diff --git a/src/components/subComponents/ModelCard.vue b/src/components/subComponents/ModelCard.vue
index 57c13f0..2c6403e 100644
--- a/src/components/subComponents/ModelCard.vue
+++ b/src/components/subComponents/ModelCard.vue
@@ -1,12 +1,18 @@
 <template>
   <div class="model-card-box" :style="`height:${height};width:${width};`">
-    <el-tabs style="height: 100%;" @before-leave="changeTabs" v-model="activeName">
+    <el-tabs
+      style="height: 100%;"
+      @before-leave="changeTabs"
+      v-model="activeName"
+    >
       <el-tab-pane label="澶у浘" name="pic">
         <div
           class="model-card-box-left"
-          :style="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
-          ? 'width: 65%;padding: 5px;box-sizing: border-box'
-          : 'width: 100%;padding: 5px;box-sizing: border-box'"
+          :style="
+            data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
+              ? 'width: 65%;padding: 5px;box-sizing: border-box'
+              : 'width: 100%;padding: 5px;box-sizing: border-box'
+          "
         >
           <div class="img-box">
             <p class="img-box-title">
@@ -14,24 +20,37 @@
             </p>
             <!-- 浜鸿劯绫诲瀷 -->
             <img-down
-              v-if="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''"
+              v-if="
+                data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
+              "
               :url="data.picMaxUrl[0]"
             ></img-down>
 
             <!-- 鏅�歽olo绫� -->
             <img-down
-              v-else-if="(data.targetInfo == null || data.targetInfo[0].picSmUrl == '') && data.picMaxUrl.length == 1"
+              v-else-if="
+                (data.targetInfo == null ||
+                  data.targetInfo[0].picSmUrl == '') &&
+                  data.picMaxUrl.length == 1
+              "
               :url="data.picMaxUrl[0]"
             ></img-down>
 
             <!-- 鎸佺画鏃堕棿yolo绫� -->
             <el-carousel
-              v-else-if="(data.targetInfo == null || data.targetInfo[0].picSmUrl == '') && data.picMaxUrl.length > 1"
+              v-else-if="
+                (data.targetInfo == null ||
+                  data.targetInfo[0].picSmUrl == '') &&
+                  data.picMaxUrl.length > 1
+              "
               trigger="click"
               height="100%"
               :autoplay="false"
             >
-              <el-carousel-item v-for="(item, index) in data.picMaxUrl" :key="index">
+              <el-carousel-item
+                v-for="(item, index) in data.picMaxUrl"
+                :key="index"
+              >
                 <img-down :url="item"></img-down>
               </el-carousel-item>
             </el-carousel>
@@ -39,31 +58,40 @@
             <!-- yolo绫诲ぇ鍥� -->
             <div
               class="describe"
-              v-if="data.targetInfo == null || data.targetInfo[0].picSmUrl == ''"
+              v-if="
+                data.targetInfo == null || data.targetInfo[0].picSmUrl == ''
+              "
             >
               <p>
-                <span
-                  class="fontStyleForModel"
-                  style="font-weight:normal"
-                >{{ data.picDate | formatTime }}</span>
+                <span class="fontStyleForModel" style="font-weight:normal">{{
+                  data.picDate | formatTime
+                }}</span>
               </p>
               <p>
                 <span class="fontStyleForModel">{{ data.cameraAddr }}</span>
                 <span
                   class="fontStyleForModel analyServer"
                   style="margin-left:20px;"
-                >{{ data.analyServerName }}</span>
+                  >{{ data.analyServerName }}</span
+                >
               </p>
               <p></p>
               <p style="width:100%">
-                <span v-for="(item,index) in data.alarmRules" :key="index+'rule'">
-                  <span class="fontStyleForModel">{{data.taskName}}</span>&nbsp;&nbsp;
+                <span
+                  v-for="(item, index) in data.alarmRules"
+                  :key="index + 'rule'"
+                >
+                  <span class="fontStyleForModel">{{ data.taskName }}</span
+                  >&nbsp;&nbsp;
                   <span
                     v-if="item.alarmLevel !== '鎾ら槻'"
                     class="fontStyleForModel"
-                  >{{item.alarmLevel}}</span>&nbsp;
-                  <span v-if="item.isLink" class="fontStyleForModel">鑱斿姩浠诲姟</span>
-                  <span v-if="index < data.alarmRules.length-1">/&nbsp;</span>
+                    >{{ item.alarmLevel }}</span
+                  >&nbsp;
+                  <span v-if="item.isLink" class="fontStyleForModel"
+                    >鑱斿姩浠诲姟</span
+                  >
+                  <span v-if="index < data.alarmRules.length - 1">/&nbsp;</span>
                 </span>
               </p>
             </div>
@@ -71,34 +99,46 @@
             <!-- 浜鸿劯绫诲ぇ鍥�  -->
             <div class="describeBigImage" v-else>
               <p>
-                <span class="fontStyleForModel">{{ data.picDate | formatTime}}</span>
+                <span class="fontStyleForModel">{{
+                  data.picDate | formatTime
+                }}</span>
               </p>
               <p class="align-right">
                 <span
                   class="fontStyleForModel text-overflow"
                   :title="data.cameraAddr"
-                >{{ data.cameraAddr }}</span>
+                  >{{ data.cameraAddr }}</span
+                >
                 <span
                   class="fontStyleForModel text-overflow"
                   :title="data.cameraAddr"
                   style="margin-left:20px;"
-                >{{ data.analyServerName }}</span>
+                  >{{ data.analyServerName }}</span
+                >
               </p>
               <p style="width:100%">
-                <span v-for="(item,index) in data.alarmRules" :key="index+'rule'">
-                  <span class="fontStyleForModel">{{data.taskName}}</span>&nbsp;&nbsp;
+                <span
+                  v-for="(item, index) in data.alarmRules"
+                  :key="index + 'rule'"
+                >
+                  <span class="fontStyleForModel">{{ data.taskName }}</span
+                  >&nbsp;&nbsp;
                   <span
                     v-if="item.alarmLevel !== '鎾ら槻'"
                     class="fontStyleForModel"
-                  >{{item.alarmLevel}}</span>&nbsp;
-                  <span v-if="item.isLink" class="fontStyleForModel">鑱斿姩浠诲姟</span>
-                  <span v-if="index < data.alarmRules.length-1">/&nbsp;</span>
+                    >{{ item.alarmLevel }}</span
+                  >&nbsp;
+                  <span v-if="item.isLink" class="fontStyleForModel"
+                    >鑱斿姩浠诲姟</span
+                  >
+                  <span v-if="index < data.alarmRules.length - 1">/&nbsp;</span>
                 </span>
               </p>
               <p style="width:100%">
                 <span
                   style="white-space: nowrap;font-weight: 600;font-size: 13px;"
-                >{{data.showLabels}}</span>
+                  >{{ data.showLabels }}</span
+                >
               </p>
             </div>
           </div>
@@ -106,20 +146,35 @@
 
         <!-- 寮规鍙充晶 -->
         <div
-          v-if="data.targetInfo && data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''"
+          v-if="
+            data.targetInfo &&
+              data.targetInfo !== null &&
+              data.targetInfo[0].picSmUrl !== ''
+          "
           class="model-card-box-right"
-          :style="data.targetInfo && data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
-          ? 'width: 35%;box-sizing: border-box;'
-          : ''"
+          :style="
+            data.targetInfo &&
+            data.targetInfo !== null &&
+            data.targetInfo[0].picSmUrl !== ''
+              ? 'width: 35%;box-sizing: border-box;'
+              : ''
+          "
         >
           <p class="img-box-title">
             <b>鎶撴媿鍥�</b>
           </p>
           <!-- 宸﹀彸涓ゅ紶鐨勪汉鑴稿姣旀ā寮� -->
-          <div class="img-box" v-if="data.baseInfo && data.baseInfo.length >= 1" ref="picSmBox">
+          <div
+            class="img-box"
+            v-if="data.baseInfo && data.baseInfo.length >= 1"
+            ref="picSmBox"
+          >
             <div class="card-img-box-compear-left">
               <!-- <img :src="'/httpImage/'+data.targetInfo[0].picSmUrl" ref="picSm" /> -->
-              <img-down :url="data.targetInfo[0].picSmUrl" :isPreview="false"></img-down>
+              <img-down
+                :url="data.targetInfo[0].picSmUrl"
+                :isPreview="false"
+              ></img-down>
             </div>
             <el-carousel
               @change="changeInitialIndex"
@@ -130,9 +185,15 @@
               v-if="data.baseInfo[0].targetPicUrl != ''"
               class="card-img-box-compear-right"
             >
-              <el-carousel-item v-for="(item, index) in data.baseInfo" :key="index">
+              <el-carousel-item
+                v-for="(item, index) in data.baseInfo"
+                :key="index"
+              >
                 <!-- <img :src="'/httpImage/'+item.targetPicUrl" /> -->
-                <img-down :url="item.targetPicUrl" :isPreview="false"></img-down>
+                <img-down
+                  :url="item.targetPicUrl"
+                  :isPreview="false"
+                ></img-down>
               </el-carousel-item>
             </el-carousel>
             <div
@@ -148,46 +209,67 @@
             </div>
           </div>
           <!-- 娌℃湁姣斿鐨勪汉鑴歌瘑鍒ā寮� -->
-          <div class="img-box" v-if="!data.baseInfo && data.targetInfo[0].picSmUrl !== '' ">
-            <div class="card-img-box-compear-left" style="width:60%;margin-top:5px">
+          <div
+            class="img-box"
+            v-if="!data.baseInfo && data.targetInfo[0].picSmUrl !== ''"
+          >
+            <div
+              class="card-img-box-compear-left"
+              style="width:60%;margin-top:5px"
+            >
               <!-- <img :src="'/httpImage/'+data.targetInfo[0].picSmUrl" /> -->
-              <img-down :url="data.targetInfo[0].picSmUrl" :isPreview="false"></img-down>
+              <img-down
+                :url="data.targetInfo[0].picSmUrl"
+                :isPreview="false"
+              ></img-down>
             </div>
           </div>
-          <div class="baseInfo" v-if="data.baseInfo && data.baseInfo[0].targetPicUrl != ''">
+          <div
+            class="baseInfo"
+            v-if="data.baseInfo && data.baseInfo[0].targetPicUrl != ''"
+          >
             <div class="baseInfo_list">
               <p>
                 <span class="labelInfo">搴曞簱</span>
                 <span
                   class="val"
                   :title="data.baseInfo[initialIndex].tableName"
-                >{{data.baseInfo[initialIndex].tableName}}</span>
+                  >{{ data.baseInfo[initialIndex].tableName }}</span
+                >
               </p>
               <p>
                 <span class="labelInfo">濮撳悕</span>
                 <span
                   class="val"
                   :title="data.baseInfo[initialIndex].targetName"
-                >{{data.baseInfo[initialIndex].targetName}}</span>
+                  >{{ data.baseInfo[initialIndex].targetName }}</span
+                >
               </p>
               <p>
                 <span class="labelInfo">鎬у埆</span>
-                <span class="val">{{data.baseInfo[initialIndex].labels | sex}}</span>
+                <span class="val">{{
+                  data.baseInfo[initialIndex].labels | sex
+                }}</span>
               </p>
               <p>
                 <span class="labelInfo">韬唤璇佸彿</span>
-                <span class="val">{{data.baseInfo[initialIndex].labels | idCard}}</span>
+                <span class="val">{{
+                  data.baseInfo[initialIndex].labels | idCard
+                }}</span>
               </p>
               <p>
                 <span class="labelInfo">鎵嬫満鍙�</span>
-                <span class="val">{{data.baseInfo[initialIndex].labels | phoneNum}}</span>
+                <span class="val">{{
+                  data.baseInfo[initialIndex].labels | phoneNum
+                }}</span>
               </p>
               <p>
                 <span class="labelInfo">浜哄憳绛夌骇</span>
                 <span
                   class="val"
                   :title="data.baseInfo[initialIndex].monitorLevel"
-                >{{data.baseInfo[initialIndex].monitorLevel}}</span>
+                  >{{ data.baseInfo[initialIndex].monitorLevel }}</span
+                >
               </p>
             </div>
           </div>
@@ -197,32 +279,49 @@
       <el-tab-pane label="瑙嗛" name="video" class="video-tabs">
         <div
           class="model-card-box-left"
-          :style="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
-          ? 'width: 65%;padding: 5px;box-sizing: border-box'
-          : 'width: 70%;padding: 5px;box-sizing: border-box;margin-left:15%'"
+          :style="
+            data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
+              ? 'width: 65%;padding: 5px;box-sizing: border-box'
+              : 'width: 70%;padding: 5px;box-sizing: border-box;margin-left:15%'
+          "
         >
           <div class="img-box">
-            <video
+            <!-- <video
               :src="'/httpImage/' + data.videoUrl"
               controls
               style="margin-top: 12px;"
-            >鎮ㄧ殑娴忚鍣ㄤ笉鏀寔 video 鏍囩銆�</video>
+            >
+              鎮ㄧ殑娴忚鍣ㄤ笉鏀寔 video 鏍囩銆�
+            </video> -->
+            <wasm-player
+              :videoUrl="data.videoUrl"
+              :isStream="false"
+            ></wasm-player>
           </div>
         </div>
         <div
           v-if="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''"
           class="model-card-box-right"
-          :style="data.targetInfo !== null &&  data.targetInfo[0].picSmUrl !== ''
-          ? 'width: 35%;box-sizing: border-box;'
-          : ''"
+          :style="
+            data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
+              ? 'width: 35%;box-sizing: border-box;'
+              : ''
+          "
         >
           <p class="img-box-title">
             <b>鎶撴媿鍥�</b>
           </p>
           <!-- 宸﹀彸涓ゅ紶鐨勪汉鑴稿姣旀ā寮� -->
-          <div class="img-box" v-if="data.baseInfo && data.baseInfo.length >= 1" ref="picSmBox">
+          <div
+            class="img-box"
+            v-if="data.baseInfo && data.baseInfo.length >= 1"
+            ref="picSmBox"
+          >
             <div class="card-img-box-compear-left">
-              <img-down :url="data.targetInfo[0].picSmUrl" :isPreview="false"></img-down>
+              <img-down
+                :url="data.targetInfo[0].picSmUrl"
+                :isPreview="false"
+              ></img-down>
             </div>
             <el-carousel
               @change="changeInitialIndex"
@@ -233,9 +332,15 @@
               class="card-img-box-compear-right"
               :arrow="data.baseInfo.length > 1 ? 'always' : 'never'"
             >
-              <el-carousel-item v-for="(item, index) in data.baseInfo" :key="index">
+              <el-carousel-item
+                v-for="(item, index) in data.baseInfo"
+                :key="index"
+              >
                 <!-- <img :src="'/httpImage/'+item.targetPicUrl" /> -->
-                <img-down :url="item.targetPicUrl" :isPreview="false"></img-down>
+                <img-down
+                  :url="item.targetPicUrl"
+                  :isPreview="false"
+                ></img-down>
               </el-carousel-item>
             </el-carousel>
             <div
@@ -251,46 +356,64 @@
             </div>
           </div>
           <!-- 娌℃湁姣斿鐨勪汉鑴歌瘑鍒ā寮� -->
-          <div class="img-box" v-if="!data.baseInfo && data.picMaxUrl ">
-            <div class="card-img-box-compear-left" style="width:60%;margin-top:5px">
+          <div class="img-box" v-if="!data.baseInfo && data.picMaxUrl">
+            <div
+              class="card-img-box-compear-left"
+              style="width:60%;margin-top:5px"
+            >
               <!-- <img :src="'/httpImage/'+data.targetInfo[0].picSmUrl" /> -->
-              <img-down :url="data.targetInfo[0].picSmUrl" :isPreview="false"></img-down>
+              <img-down
+                :url="data.targetInfo[0].picSmUrl"
+                :isPreview="false"
+              ></img-down>
             </div>
           </div>
-          <div class="baseInfo" v-if="data.baseInfo && data.baseInfo[0].targetPicUrl != ''">
+          <div
+            class="baseInfo"
+            v-if="data.baseInfo && data.baseInfo[0].targetPicUrl != ''"
+          >
             <div class="baseInfo_list">
               <p>
                 <span class="labelInfo">搴曞簱</span>
                 <span
                   class="val"
                   :title="data.baseInfo[initialIndex].tableName"
-                >{{data.baseInfo[initialIndex].tableName}}</span>
+                  >{{ data.baseInfo[initialIndex].tableName }}</span
+                >
               </p>
               <p>
                 <span class="labelInfo">濮撳悕</span>
                 <span
                   class="val"
                   :title="data.baseInfo[initialIndex].targetName"
-                >{{data.baseInfo[initialIndex].targetName}}</span>
+                  >{{ data.baseInfo[initialIndex].targetName }}</span
+                >
               </p>
               <p>
                 <span class="labelInfo">鎬у埆</span>
-                <span class="val">{{data.baseInfo[initialIndex].labels | sex}}</span>
+                <span class="val">{{
+                  data.baseInfo[initialIndex].labels | sex
+                }}</span>
               </p>
               <p>
                 <span class="labelInfo">韬唤璇佸彿</span>
-                <span class="val">{{data.baseInfo[initialIndex].labels | idCard}}</span>
+                <span class="val">{{
+                  data.baseInfo[initialIndex].labels | idCard
+                }}</span>
               </p>
               <p>
                 <span class="labelInfo">鎵嬫満鍙�</span>
-                <span class="val">{{data.baseInfo[initialIndex].labels | phoneNum}}</span>
+                <span class="val">{{
+                  data.baseInfo[initialIndex].labels | phoneNum
+                }}</span>
               </p>
               <p>
                 <span class="labelInfo">浜哄憳绛夌骇</span>
                 <span
                   class="val"
                   :title="data.baseInfo[initialIndex].monitorLevel"
-                >{{data.baseInfo[initialIndex].monitorLevel}}</span>
+                  >{{ data.baseInfo[initialIndex].monitorLevel }}</span
+                >
               </p>
             </div>
           </div>
@@ -300,54 +423,67 @@
   </div>
 </template>
 <script>
-Date.prototype.Format = function (fmt) {
+Date.prototype.Format = function(fmt) {
   var o = {
-    "M+": this.getMonth() + 1, //鏈堜唤 
-    "d+": this.getDate(), //鏃� 
-    "H+": this.getHours(), //灏忔椂 
-    "m+": this.getMinutes(), //鍒� 
-    "s+": this.getSeconds(), //绉� 
-    "q+": Math.floor((this.getMonth() + 3) / 3), //瀛e害 
-    "S": this.getMilliseconds() //姣 
-  };
-  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+    'M+': this.getMonth() + 1, //鏈堜唤
+    'd+': this.getDate(), //鏃�
+    'H+': this.getHours(), //灏忔椂
+    'm+': this.getMinutes(), //鍒�
+    's+': this.getSeconds(), //绉�
+    'q+': Math.floor((this.getMonth() + 3) / 3), //瀛e害
+    S: this.getMilliseconds(), //姣
+  }
+  if (/(y+)/.test(fmt))
+    fmt = fmt.replace(
+      RegExp.$1,
+      (this.getFullYear() + '').substr(4 - RegExp.$1.length)
+    )
   for (var k in o)
-    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
-  return fmt;
+    if (new RegExp('(' + k + ')').test(fmt))
+      fmt = fmt.replace(
+        RegExp.$1,
+        RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
+      )
+  return fmt
 }
 
-/* eslint-disable */
-import CameraPlayer from "@/components/player";
-import imgDown from "@/components/subComponents/imgDown"
+import WasmPlayer from '@/components/wasmPlayer'
+import imgDown from '@/components/subComponents/imgDown'
 export default {
   components: {
-    CameraPlayer,
-    imgDown
+    WasmPlayer,
+    imgDown,
   },
   props: {
     height: {
       type: String,
-      default: "100%"
+      default: '100%',
     },
     width: {
       type: String,
-      default: "100%"
+      default: '100%',
     },
-    data: ""
+    data: {
+      type: Object,
+      require: false,
+      default: function() {
+        return {}
+      },
+    },
   },
   filters: {
     formatTime(t) {
-      return new Date(t).Format("yyyy-MM-dd HH:mm:ss")
+      return new Date(t).Format('yyyy-MM-dd HH:mm:ss')
     },
     percentage(score) {
-      return score.toFixed(2) + "%"
+      return score.toFixed(2) + '%'
     },
     sex(v) {
       try {
         let obj = JSON.parse(v)
         return obj.sex
       } catch (error) {
-        return v.split("/")[0]
+        return v.split('/')[0]
       }
     },
     idCard(v) {
@@ -355,7 +491,7 @@
         let obj = JSON.parse(v)
         return obj.idCard
       } catch (error) {
-        return v.split("/")[1]
+        return v.split('/')[1]
       }
     },
     phoneNum(v) {
@@ -363,12 +499,12 @@
         let obj = JSON.parse(v)
         return obj.phone
       } catch (error) {
-        return v.split("/")[2]
+        return v.split('/')[2]
       }
-    }
+    },
   },
   mounted() {
-    console.log('ModelCard data', this.data);
+    console.log('ModelCard data', this.data)
     console.log(this.data.baseInfo)
     console.log(this.initialIndex)
     //this.VideoPhotoData.activeName = "pic"
@@ -377,26 +513,26 @@
     return {
       activeName: 'pic',
       initialIndex: 0,
-    };
+    }
   },
   methods: {
     changeTabs(activeName, oldActiveName) {
-      console.log(activeName, oldActiveName);
+      console.log(activeName, oldActiveName)
     },
     changeInitialIndex(index) {
-      this.initialIndex = index;
+      this.initialIndex = index
     },
     downloadfile() {
-      this.filecontent = "this is my file content";
-      let a = document.createElement('a');
+      this.filecontent = 'this is my file content'
+      let a = document.createElement('a')
 
-      a.href = "data:text/json;charset=utf-8," + this.filecontent;
+      a.href = 'data:text/json;charset=utf-8,' + this.filecontent
       // a.url = "http://192.168.20.112:6154/93,02c5aea4fc614e";
-      a.download = "video.mp4";
-      a.click();
-    }
+      a.download = 'video.mp4'
+      a.click()
+    },
   },
-};
+}
 </script>
 <style lang="scss">
 .fontStyleForModel {
diff --git a/src/components/wasmPlayer/index.vue b/src/components/wasmPlayer/index.vue
new file mode 100644
index 0000000..447a4a5
--- /dev/null
+++ b/src/components/wasmPlayer/index.vue
@@ -0,0 +1,740 @@
+<template>
+  <div class="video-player">
+    <canvas
+      v-show="showArea"
+      id="area-canvas"
+      ref="areaCanvas"
+      width="960"
+      height="540"
+    ></canvas>
+    <div class="container" id="videoPlayer">
+      <div class="canvasDiv">
+        <div class="loadEffect" id="loading" style="display:none;">
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+        </div>
+        <canvas
+          ref="playCanvas"
+          id="paly-canvas"
+          width="960"
+          height="540"
+        ></canvas>
+      </div>
+
+      <!-- 鎺у埗鏉� -->
+      <section
+        class="jsmodern-video-panel"
+        :style="{ display: isStream ? 'none' : 'block' }"
+      >
+        <!-- 鎾斁/鏆傚仠 -->
+        <b
+          :class="
+            playerStatus == 0 ? 'jsmodern-video-play' : 'jsmodern-video-pause'
+          "
+          @click="playVideo"
+        ></b>
+
+        <!-- 鏃堕棿 -->
+        <span class="jsmodern-video-start" ref="timeLabel"
+          >00:00:00/00:00:00</span
+        >
+
+        <!-- 杩涘害鏉� -->
+        <div>
+          <input
+            class="jsmodern-video-linebox"
+            ref="timeTrack"
+            type="range"
+            value="0"
+          />
+        </div>
+
+        <!-- 澹伴煶 -->
+        <b class="jsmodern-video-volume"></b>
+        <!-- <div class="jsmodern-video-volumebox">
+          <div class="jsmodern-video-volumeline"></div>
+          <b class="jsmodern-video-volumedot"></b>
+        </div> -->
+
+        <!-- 鍏ㄥ睆 -->
+        <b
+          class="jsmodern-video-fullin"
+          @click="fullScreen"
+          :disable="false"
+        ></b>
+      </section>
+
+      <!-- 澶ф挱鏀炬寜閽� -->
+      <div v-show="!isStream">
+        <span class="video-btn" v-show="playerStatus == 0" @click="playVideo"
+          ><img src="./wasm/img/bo1.png"
+        /></span>
+
+        <!-- 涓婁竴涓� -->
+        <span class="video-prve" v-show="showPrev">
+          <i class="el-icon-arrow-left" @click="playPrev"></i>
+        </span>
+
+        <!-- 涓嬩竴涓� -->
+        <span class="video-next" v-show="showNext">
+          <i class="el-icon-arrow-right" @click="playNext"></i>
+        </span>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+/*
+  2021.09.22 娣诲姞澶氫釜褰曞儚鍦板潃鐨勫鐞�, 涓庡綍鍍忔ā鍧楃害瀹�, 鐢� || 鍒嗗壊澶氫釜瑙嗛鍦板潃, 鍓嶇澶勭悊鎾斁.
+*/
+import { Player } from './wasm/player'
+import VideoRuleData from '@/Pool/VideoRuleData'
+import { getAllPolygon } from '@/api/polygon'
+export default {
+  name: 'CameraPlayer',
+  props: {
+    videoUrl: {
+      type: String,
+      // default: "ws://192.168.1.182:10101/ws"
+      default: `${location.protocol === 'https' ? 'wss' : 'ws'}://${
+        location.host
+      }/ws`,
+    },
+    cameraName: {
+      type: String,
+      default: '',
+    },
+    cameraID: {
+      type: String,
+      default: 'C4668FD0-3CAE-C31F-C21E-28B7001243C4',
+    },
+    rtspUrl: {
+      type: String,
+      default:
+        'rtsp://admin:a1234567@192.168.1.201:554/h264/ch1/main/av_stream',
+    },
+    isRunning: {
+      type: Boolean,
+      default: false,
+    },
+    isGb: {
+      type: Boolean,
+      default: false,
+    },
+    showArea: {
+      type: Boolean,
+      default: false,
+    },
+    isStream: {
+      type: Boolean,
+      default: true,
+    },
+  },
+
+  computed: {
+    poster() {
+      return '/images/player/player_poster.gif?t=' + Math.random()
+    },
+    showPrev() {
+      return this.playerIndex - 1 >= 0
+    },
+    showNext() {
+      return this.playerIndex + 1 < this.videoUrls.length
+    },
+  },
+  data() {
+    return {
+      player: null,
+      playerId: 0,
+      Camera: new VideoRuleData(),
+      showCanvas: true,
+      canvasData: {
+        line: [],
+        rect: [], // {id:'uuid', name: '鐭╁舰1', location: [{ x: 20, y: 30 }, { x: 20, y: 60 }, { x: 100, y: 60 }, { x: 100, y: 30 }] }
+        arrow: [],
+        polygon: [],
+      },
+      //showProportion: 3.2,
+      //showProportionY: 3.58,
+      // showProportion: 1.036,
+      // showProportionY: 1.039,
+      showProportion: 1,
+      showProportionY: 1,
+      canvas: null,
+      ctx: null,
+      canvasWidth: 0,
+      canvasHeight: 0,
+      algoDataSocket: null,
+      playerStatus: 0,
+      videoUrls: [],
+      playerIndex: 0,
+    }
+  },
+  watch: {
+    rtspUrl: function(newVal, oldVal) {
+      if (newVal !== oldVal) {
+        if (this.player) {
+          this.player.stop()
+          !!this.algoDataSocket && this.algoDataSocket.close()
+        }
+        this.$nextTick(() => {
+          this.playVideo()
+        })
+      }
+    },
+  },
+  mounted() {
+    this.player = new Player()
+
+    // 褰曞儚URL澶勭悊, 鍙兘瀛樺湪澶氫釜褰曞儚鍦板潃
+    if (!this.isStream) {
+      this.videoUrls = this.videoUrl.split('||')
+    }
+
+    if (this.isStream) {
+      this.playVideo()
+      this.$nextTick(() => {
+        this.canvas = this.$refs.areaCanvas
+        this.ctx = this.canvas.getContext('2d')
+        this.ctx.lineWidth = 1
+        this.initArea()
+      })
+    }
+  },
+  beforeDestroy() {
+    this.player.stop()
+  },
+  methods: {
+    checkConnect(id) {
+      if (id !== this.playerId) {
+        return
+      }
+
+      if (this.wfs.websocketLoader && this.wfs.websocketLoader.client) {
+        if (this.wfs.websocketLoader.client.disconnected) {
+          this.playVideo()
+          console.log('瀹炴椂瑙嗛宸叉柇寮�锛屾鍦ㄩ噸杩�')
+          return
+        }
+      }
+
+      let _this = this
+      setTimeout(() => {
+        _this.checkConnect(id)
+      }, 10000)
+    },
+    getUuid() {
+      var s = []
+      var hexDigits = '0123456789abcdefghijkopqrst'
+      for (var i = 0; i < 36; i++) {
+        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
+      }
+      s[14] = '4' //聽bits聽12-15聽of聽the聽time_hi_and_version聽field聽to聽0010
+      s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) //聽bits聽6-7聽of聽the聽clock_seq_hi_and_reserved聽to聽01
+      s[8] = s[13] = s[18] = s[23] = '-'
+      var uuid = s.join('')
+      return uuid
+    },
+    // 鍥炴樉cavas鏁版嵁
+    // 鐐瑰嚮閫変腑鍙樿壊 灏嗗綋鍓嶉〉闈㈡墍鏈夎矾寰勯噸缁樺垽鏂綋鍓嶉紶鏍囩殑鍧愭爣鍦ㄥ摢涓浘褰㈠唴 濡傛灉涓嶄紶鍧愭爣鍙傛暟灏辨槸鍥炴樉鐨勬柟娉�
+    clickSelect(e) {
+      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
+      let _this = this // 闆嗗悎涓亶鍘嗛渶瑕佸皢this杞瓨涓�涓嬩娇鐢�
+      _this.canvasData.line.forEach(function(v, i) {
+        _this.ctx.strokeStyle = 'yellow'
+        _this.ctx.beginPath()
+        _this.ctx.moveTo(
+          v.location[0].x / _this.showProportion,
+          v.location[0].y / _this.showProportion
+        )
+        _this.ctx.lineTo(
+          v.location[1].x / _this.showProportion,
+          v.location[1].y / _this.showProportion
+        )
+        _this.ctx.stroke()
+        _this.canvas.style.cursor = 'default'
+      })
+      _this.canvasData.rect.forEach(function(v, i) {
+        _this.ctx.strokeStyle = 'yellow'
+        _this.ctx.beginPath()
+        _this.ctx.moveTo(
+          v.location[0].x / _this.showProportion,
+          v.location[0].y / _this.showProportion
+        )
+        _this.ctx.lineTo(
+          v.location[1].x / _this.showProportion,
+          v.location[1].y / _this.showProportion
+        )
+        _this.ctx.lineTo(
+          v.location[2].x / _this.showProportion,
+          v.location[2].y / _this.showProportion
+        )
+        _this.ctx.lineTo(
+          v.location[3].x / _this.showProportion,
+          v.location[3].y / _this.showProportion
+        )
+        _this.ctx.lineTo(
+          v.location[0].x / _this.showProportion,
+          v.location[0].y / _this.showProportion
+        )
+        _this.ctx.stroke()
+        _this.canvas.style.cursor = 'default'
+      })
+      _this.canvasData.arrow.forEach(function(v, i) {
+        _this.ctx.strokeStyle = 'yellow'
+        _this.drawArrow(
+          _this.ctx,
+          v.location[0].x / _this.showProportion,
+          v.location[0].y / _this.showProportion,
+          v.location[1].x / _this.showProportion,
+          v.location[1].y / _this.showProportion,
+          20,
+          30,
+          'yellow'
+        )
+        _this.canvas.style.cursor = 'default'
+      })
+      _this.canvasData.polygon.forEach(function(v, i) {
+        if (v.location.length === 0) {
+          return
+        }
+        _this.ctx.strokeStyle = 'yellow'
+        _this.ctx.beginPath()
+        _this.ctx.moveTo(
+          v.location[0].x / _this.showProportion,
+          v.location[0].y / _this.showProportionY
+        )
+        for (let i = 1; i < v.location.length; i++) {
+          _this.ctx.lineTo(
+            v.location[i].x / _this.showProportion,
+            v.location[i].y / _this.showProportionY
+          )
+        }
+        _this.ctx.closePath()
+        _this.ctx.stroke()
+        _this.canvas.style.cursor = 'default'
+      })
+    },
+
+    // 绠ご缁樺埗鍑芥暟
+    drawArrow(
+      ctx,
+      fromX,
+      fromY,
+      toX,
+      toY,
+      theta = 30,
+      headlen = 10,
+      width = 1,
+      color = 'yellow'
+    ) {
+      // ctx锛欳anvas缁樺浘鐜
+      // fromX, fromY锛氳捣鐐瑰潗鏍囷紙涔熷彲浠ユ崲鎴恜1锛屽彧涓嶈繃瀹冩槸涓�涓暟缁勶級
+      // toX, toY锛氱粓鐐瑰潗鏍� (涔熷彲浠ユ崲鎴恜2锛屽彧涓嶈繃瀹冩槸涓�涓暟缁�)
+      // theta锛氫笁瑙掓枩杈逛竴鐩寸嚎澶硅
+      // headlen锛氫笁瑙掓枩杈归暱搴�
+      // width锛氱澶寸嚎瀹藉害
+      // color锛氱澶撮鑹�
+      // theta = typeof theta !== "undefined" ? theta : 30;
+      // headlen = typeof theta !== "undefined" ? headlen : 10;
+      // width = typeof width !== "undefined" ? width : 1;
+      // color = typeof color !== "undefined" ? color : "yellow";
+      // 璁$畻鍚勮搴﹀拰瀵瑰簲鐨凱2,P3鍧愭爣
+      let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI
+      let angle1 = ((angle + theta) * Math.PI) / 180
+      let angle2 = ((angle - theta) * Math.PI) / 180
+      let topX = headlen * Math.cos(angle1)
+      let topY = headlen * Math.sin(angle1)
+      let botX = headlen * Math.cos(angle2)
+      let botY = headlen * Math.sin(angle2)
+
+      ctx.save()
+      ctx.beginPath()
+      let arrowX = fromX - topX
+      let arrowY = fromY - topY
+      ctx.moveTo(arrowX, arrowY)
+      ctx.moveTo(fromX, fromY)
+      ctx.lineTo(toX, toY)
+      arrowX = toX + topX
+      arrowY = toY + topY
+      ctx.moveTo(arrowX, arrowY)
+      ctx.lineTo(toX, toY)
+      arrowX = toX + botX
+      arrowY = toY + botY
+      ctx.lineTo(arrowX, arrowY)
+      ctx.strokeStyle = color
+      ctx.lineWidth = width
+      ctx.stroke()
+      ctx.restore()
+    },
+
+    // 鍥炴樉鍥惧舰澶囨敞
+    showRemarks(x, y, remarks) {
+      this.ctx.moveTo(x, y - 10) // 鍥犱负鏀惧ぇ涔嬪悗鏄痽-20锛屾墍浠ョ缉灏忕増鐨勪负y-10
+      this.ctx.fillStyle = 'green' // 璁剧疆濉厖棰滆壊涓虹豢鑹�
+      this.ctx.font = '10px "寰蒋闆呴粦"' // 璁剧疆瀛椾綋
+      this.ctx.textBaseline = 'bottom' // 璁剧疆瀛椾綋搴曠嚎瀵归綈缁樺埗鍩虹嚎
+      this.ctx.textAlign = 'left' // 璁剧疆瀛椾綋瀵归綈鐨勬柟寮�
+      this.ctx.fillText(remarks, x, y - 10) // 濉厖鏂囧瓧
+    },
+    getCanvasData(data) {
+      let polyon = { ...data }
+      polyon.camera_id = this.Camera.cameraId
+      savePolygon(polyon).then((rsp) => {
+        this.Camera.getPolygon()
+        this.Camera.getCameraTask()
+      })
+    },
+    setWidthHeight() {
+      this.canvasWidth = this.$refs.videoPlayer.offsetWidth
+      this.canvasHeight = this.$refs.videoPlayer.offsetHeight
+      console.log(this.canvasWidth, this.canvasHeight)
+    },
+    async initArea() {
+      if (!this.showCanvas) {
+        return
+      }
+
+      const res = await getAllPolygon({
+        cameraId: this.TreeDataPool.selectedNode.id,
+      })
+      this.canvasData.line = res.data.line
+      this.canvasData.rect = res.data.rect
+      this.canvasData.arrow = res.data.arrow
+      this.canvasData.polygon = res.data.polygon
+      this.clickSelect(this.canvasData)
+    },
+    initAlgoDataWebScoket() {
+      if (typeof WebSocket === 'undefined') {
+        console.log('error,鎮ㄧ殑娴忚鍣ㄤ笉鏀寔socket')
+      } else {
+        this.algoDataSocket = new WebSocket()
+        this.algoDataSocket.onopen = () => {
+          console.log('socket杩炴帴鎴愬姛')
+        }
+        this.algoDataSocket.onerror = () => {
+          console.log('杩炴帴閿欒')
+        }
+        this.algoDataSocket.onmessage = (msg) => {
+          console.log(msg)
+        }
+      }
+    },
+    playVideo() {
+      if (this.isStream && this.rtspUrl == '') {
+        return
+      }
+
+      let payload = ''
+      let url = ''
+      if (this.isStream) {
+        if (this.cameraID == '') {
+          this.cameraID = this.getUuid()
+        }
+
+        payload = JSON.stringify({
+          cameraID: this.cameraID,
+          rtspUrl: this.rtspUrl,
+          isRunning: this.isRunning,
+          isGb28181: this.isGb,
+        })
+
+        url = this.videoUrl
+      } else {
+        url = '/httpImage/' + this.videoUrls[this.playerIndex]
+      }
+
+      if (url == '') {
+        return
+      }
+
+      if (this.player.hPlayer == 0) {
+        this.player.play(
+          url,
+          this.$refs.playCanvas,
+          this.isStream,
+          this.$refs.timeTrack,
+          this.$refs.timeLabel,
+          payload
+        )
+      } else if (this.player.PlayOrPause == 0) {
+        this.player.resume()
+      } else {
+        this.player.pause()
+      }
+
+      this.playerStatus = this.player.PlayOrPause
+      let randomId = this.getUuid()
+      this.checkConnect(randomId)
+    },
+
+    stopVideo() {
+      if (this.player.hPlayer == 0) return
+
+      this.player.stop()
+    },
+
+    fullScreen() {
+      this.player.fullscreen()
+    },
+
+    playPrev() {
+      this.playerIndex--
+      this.player.stop()
+      this.playVideo()
+    },
+
+    playNext() {
+      this.playerIndex++
+      this.player.stop()
+      this.playVideo()
+      console.log(this.playerIndex, this.videoUrls.length)
+    },
+  },
+}
+</script>
+
+<style lang="scss">
+#paly-canvas,
+#area-canvas {
+  background: transparent;
+  position: absolute;
+  top: 0;
+  left: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+
+video {
+  object-fit: fill;
+  width: 100%;
+  height: 100%;
+}
+.video-player {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  background-color: #000000;
+
+  .jsmodern-video-panel {
+    display: none;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    z-index: 2147483648;
+    width: 100%;
+    height: 40px;
+    line-height: 40px;
+    color: #fff;
+    background: -webkit-linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.9));
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    user-select: none;
+  }
+
+  .jsmodern-video-panel.jsmodern-video-panelFull {
+    left: 50%;
+    -webkit-transform: translate(-50%, -10px);
+    -ms-transform: translate(-50%, -10px);
+    transform: translate(-50%, -10px);
+    padding: 3px 5px;
+    border-radius: 8px;
+  }
+
+  .jsmodern-video-linebox {
+    height: 3px;
+    background: rgba(255, 255, 255, 0.25);
+    border-radius: 3px;
+    width: 460px;
+    width: -webkit-calc(100% - 220px);
+    width: -moz-calc(100% - 220px);
+    width: calc(100% - 220px);
+    float: left;
+    margin: 19px 0 0 65px;
+    position: relative;
+    cursor: pointer;
+  }
+
+  .jsmodern-video-pass {
+    position: absolute;
+    border-radius: 3px;
+    height: 100%;
+    background: #f81e3d;
+  }
+
+  .jsmodern-video-linedot {
+    width: 6px;
+    height: 6px;
+    background: #fff;
+    border-radius: 3px;
+    -webkit-transform: scale(1.8);
+    -ms-transform: scale(1.8);
+    transform: scale(1.8);
+    position: absolute;
+  }
+
+  .jsmodern-video-panel b {
+    cursor: pointer;
+  }
+
+  .jsmodern-video-panel b,
+  .jsmodern-video-panel span {
+    display: block;
+    float: left;
+  }
+
+  .jsmodern-video-panel span {
+    font-size: 12px;
+    cursor: default;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    user-select: none;
+  }
+
+  .jsmodern-video-start {
+    margin-left: 10px;
+  }
+
+  .jsmodern-video-start + span {
+    width: 14px;
+    height: 12px;
+    text-align: center;
+    line-height: 12px;
+    font-size: 10px;
+    overflow: hidden;
+    margin-top: 13px;
+    -webkit-transform: scale(1, 0.9) translateY(1px);
+    -ms-transform: scale(1, 0.9) translateY(1px);
+    transform: scale(1, 0.9) translateY(1px);
+    -webkit-transform-origin: left top;
+    -ms-transform-origin: left top;
+    transform-origin: left top;
+  }
+
+  .jsmodern-video-start,
+  .jsmodern-video-end {
+    width: 39px;
+    text-align: center;
+  }
+
+  .jsmodern-video-volumebox {
+    width: 80px;
+    height: 6px;
+    background: rgba(255, 255, 255, 0.25);
+    border-radius: 3px;
+    float: left;
+    margin: 18px 0 0 7px;
+    position: relative;
+    cursor: pointer;
+  }
+
+  .jsmodern-video-volumeline {
+    width: 40px;
+    height: 6px;
+    background: #f81e3d;
+    border-radius: 3px;
+    margin-top: 0;
+  }
+
+  .jsmodern-video-volumedot {
+    width: 6px;
+    height: 6px;
+    background: #fff;
+    border-radius: 3px;
+    margin: -6px 0 0 37px;
+    -webkit-transform: scale(1.8);
+    -ms-transform: scale(1.8);
+    transform: scale(1.8);
+    position: absolute;
+  }
+
+  .jsmodern-video-play,
+  .jsmodern-video-pause,
+  .jsmodern-video-volume,
+  .jsmodern-video-fullin {
+    width: 18px;
+    height: 18px;
+    margin-top: 11px;
+    background-position: center;
+    background-repeat: no-repeat;
+  }
+
+  .jsmodern-video-play {
+    margin-left: 10px;
+    background-image: url(data:img/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAe0lEQVR42q2UQRGAIBREiWAEIhjhRzCKDbCBRjGCDaQBRqDBdzntgRvLm3nXN6sMhIa7G0xBgqHGC1c9RNKcENeZHiInXLQQKdDUUL9OD3GdGOrXaSGSZ4QuddEDo/KPPrgpx1/hwc8YC90wKlckQ1MubYW79IzwOMf4AZCzZlJ6pNv5AAAAAElFTkSuQmCC);
+  }
+
+  .jsmodern-video-pause {
+    margin-left: 10px;
+    background-image: url(data:img/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAANUlEQVR42u3MMQoAAAgCwP4/9aR+VjQINtTcoNBicobkTNiS/vEQvSBBggR9hILOD8h5i74A46kzKYwr0EYAAAAASUVORK5CYII=);
+  }
+
+  .jsmodern-video-volume {
+    margin-left: 15px;
+    background-image: url(data:img/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAqklEQVR42tWT0QmDMBCGHcENXMEBhGaL9rEjZATffKwDZJdmgy7QHZo33zz/0AscBmNaCOIPH3Ke+USTq84ZIrqDdnXPgGuuoAVP4KMi0TddSlCDB5BR3GvEcy/wCYUCF8HNNwFtiBwwQco9jSKKBZQQaa4brt+en0W8eAJGiN2/IusRIiouKv9puA5bP7uXhDfsbP8gtn8GOnUgx8wD6XJHxO6NSNGhPT4LSrtjI5LQNtEAAAAASUVORK5CYII=);
+  }
+
+  .jsmodern-video-muted {
+    background-image: url(data:img/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAA00lEQVR42s2UsQ3CMBBFqZAokNLQoozgCWJ3NAxAg5QRGIEFEOkpgBFgAbIKC0AoU5nv6CJ9GQI6lIIvPcXxyd93di4D730v9Gf0Xc1mOTA0pTMKi8EFBDm1EQIJ2AKWldiw64wcsMQC3EGsDEzBhLPAM5XBi0r/XjNwBUfKxMimhcYoAzsZ78mkAkZlJBUc5L1uTbSlWbrJWuZOYU5tFJVzbsvUGs3BDTzEkMtsDnsdsQJVR0YbsOTrlzXJpw+yACwnsfGvLVLqWkTftCM2+r//0RPE3HMNwpwYwQAAAABJRU5ErkJggg==);
+  }
+
+  .jsmodern-video-fullin {
+    margin-left: 15px;
+    background-image: url(data:img/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAKlBMVEVMaXH////////////////////////////////////////////////////m1kuZAAAADXRSTlMAYBAw79DwIM9wgG9/QM+KqQAAAF5JREFUeNqNj0sSwCAIQ6Pit+X+1y2GOs7UTbNA8kYjQE05wpTK7LG8EwcdrwZB7hrcBx1FYfcDCY9UEGdbrFbiBIqpFf90PmGo7NDvtwJt1x7slmN0graWEwIny+sDBBUDznqlFGYAAAAASUVORK5CYII=);
+  }
+
+  .jsmodern-video-fullout {
+    margin-left: 15px;
+    background-image: url(data:img/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAJ1BMVEVMaXH////////////////////////////////////////////////c+C/6AAAADHRSTlMAgBDQz39QIMBAML9Nf8RqAAAAaElEQVR42r2QQQ7AIAgEV6CIlv+/t3Ap3E2cyyojxIBb7JfqQu/+z+ZCIAU0QtzqEbtMGcCIcCZ0454iIuvFLDHRICkhvUNHsICVqThBnyBHZSqK4+/2Ok9OEdGNOdcSuS1xW2+3jUt8eaUDz3DmFVcAAAAASUVORK5CYII=);
+  }
+
+  b.jsmodern-video-fullFalse {
+    opacity: 0.5;
+    cursor: default;
+  }
+}
+
+.video-player:hover {
+  .jsmodern-video-panel {
+    display: block !important;
+  }
+}
+
+.video-btn {
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  display: block;
+  width: 70px;
+  height: 70px;
+  margin-left: -35px;
+  margin-top: -35px;
+  cursor: pointer;
+  z-index: 10;
+}
+
+.video-prve,
+.video-next {
+  position: absolute;
+  top: 45%;
+  font-size: 30px;
+  color: #bdbdbd;
+  cursor: pointer;
+}
+
+.video-prve {
+  left: 0px;
+}
+
+.video-next {
+  right: 0px;
+}
+</style>
diff --git a/src/components/wasmPlayer/wasm/img/bo1.png b/src/components/wasmPlayer/wasm/img/bo1.png
new file mode 100644
index 0000000..b95e436
--- /dev/null
+++ b/src/components/wasmPlayer/wasm/img/bo1.png
Binary files differ
diff --git a/src/components/wasmPlayer/wasm/index.html b/src/components/wasmPlayer/wasm/index.html
new file mode 100644
index 0000000..cb120ff
--- /dev/null
+++ b/src/components/wasmPlayer/wasm/index.html
@@ -0,0 +1,143 @@
+锘�<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8" />
+    <title>WASM TEST</title>
+    <meta name="apple-mobile-web-app-capable" content="yes" />
+    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+    <meta name="apple-touch-fullscreen" content="yes" />
+    <meta name="format-detection" content="telephone=no, email=no" />
+    <link rel="stylesheet" href="styles/style.css" />
+  </head>
+  <body>
+    <div class="container" id="videoPlayer">
+      <div class="sideBar">
+        <span class="no-padding">
+          <img
+            src="img/home.png"
+            class="left"
+            id="btnHome"
+            title="Visit My Homepage"
+            onclick="window.open('https://blog.csdn.net/sonysuqin')"
+          />
+        </span>
+        <div id="input">
+          <select id="protocol" onchange="onSelectProto()">
+            <option value="h265_high">h265_high</option>
+            <option value="basicH265">h265_basic</option>
+            <option value="basicH264">h264</option>
+            <option value="h265_stream">h265_stream</option>
+            <option value="h264_stream">h264_stream</option>
+          </select>
+          <input type="text" id="inputUrl" style="width:300px" />
+        </div>
+      </div>
+      <div class="canvasDiv">
+        <div class="loadEffect" id="loading" style="display:none;">
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+          <span></span>
+        </div>
+        <canvas id="playCanvas" width="852" height="480"></canvas>
+      </div>
+      <div class="sideBar">
+        <span class="no-padding">
+          <img
+            src="img/play.png"
+            class="left"
+            id="btnPlayVideo"
+            onclick="OnBnClickedPlayVideo()"
+          />
+        </span>
+        <span class="no-padding" style=" padding-left:5px;">
+          <img
+            src="img/stop.png"
+            class="left"
+            id="btnStopVideo"
+            onclick="OnBnClickedStopVideo()"
+          />
+        </span>
+        <span class="track-padding"></span>
+        <span class="no-padding">
+          <input id="timeTrack" type="range" value="0" />
+        </span>
+        <span class="no-padding" style=" padding-left:10px;">
+          <label id="timeLabel">00:00:00/00:00:00</label>
+        </span>
+        <span class="no-padding right">
+          <img
+            src="img/fullscreen.png"
+            class="right"
+            id="btnFullscreen"
+            onclick="OnBnClickedFullscreen()"
+          />
+        </span>
+      </div>
+    </div>
+
+    <script type="text/javascript" src="pcm-player.js"></script>
+    <script type="text/javascript" src="webgl.js"></script>
+    <script type="text/javascript" src="player.js"></script>
+
+    <script type="text/javascript">
+      var defaultProtos = {
+        h265_high: { url: 'video/h265_high.mp4', stream: false },
+        basicH265: { url: 'video/smart-ai-h265.mp4', stream: false },
+        basicH264: { url: 'video/smart-ai-h264.mp4', stream: false },
+        h265_stream: { url: 'h265', stream: true },
+        h264_stream: { url: 'h264', stream: true },
+      }
+      document.getElementById('inputUrl').value =
+        defaultProtos['h265_high']['url']
+
+      self.PlayObj = new Player()
+
+      function OnBnClickedPlayVideo() {
+        var button = document.getElementById('btnPlayVideo')
+        if (self.PlayObj.hPlayer == 0 || self.PlayObj.PlayOrPause == 0)
+          button.src = 'img/pause.png'
+        else button.src = 'img/play.png'
+
+        if (self.PlayObj.hPlayer == 0) {
+          var protoList = document.getElementById('protocol')
+          self.PlayObj.play(
+            document.getElementById('inputUrl').value,
+            document.getElementById('playCanvas'),
+            defaultProtos[protoList.options[protoList.selectedIndex].value]
+              .stream,
+            document.getElementById('timeTrack'),
+            document.getElementById('timeLabel')
+          )
+        } else if (self.PlayObj.PlayOrPause == 0) self.PlayObj.resume()
+        else self.PlayObj.pause()
+      }
+
+      function OnBnClickedStopVideo() {
+        if (self.PlayObj.hPlayer == 0) return
+
+        var button = document.getElementById('btnPlayVideo')
+        button.value = 'Play'
+        button.src = 'img/play.png'
+
+        self.PlayObj.stop()
+      }
+
+      function OnBnClickedFullscreen() {
+        self.PlayObj.fullscreen()
+      }
+
+      function onSelectProto() {
+        var protoList = document.getElementById('protocol')
+        var proto = protoList.options[protoList.selectedIndex].value
+        var protoObj = defaultProtos[proto]
+        var inputUrl = document.getElementById('inputUrl')
+        inputUrl.value = protoObj['url']
+      }
+    </script>
+  </body>
+</html>
diff --git a/src/components/wasmPlayer/wasm/pcm-player.js b/src/components/wasmPlayer/wasm/pcm-player.js
new file mode 100644
index 0000000..2e71f7f
--- /dev/null
+++ b/src/components/wasmPlayer/wasm/pcm-player.js
@@ -0,0 +1,227 @@
+export function PCMPlayer(option)
+{
+	this.init(option);
+}
+
+PCMPlayer.prototype.init=function(option)
+{
+	var defaults={
+	encoding: '16bitInt',
+	channels:1,
+	sampleRate:8000,
+	flushingTime:1000
+	};
+	this.option=Object.assign({},defaults,option);
+	this.samples=new Float32Array();
+	this.flush=this.flush.bind(this);
+	this.interval=setInterval(this.flush,this.option.flushingTime);
+	this.maxValue=this.getMaxValue();
+	this.typedArray=this.getTypedArray();
+	this.createContext();
+};
+
+PCMPlayer.prototype.getMaxValue=function()
+{
+	var encodings={
+		'8bitInt': 128,
+		'16bitInt':32768,
+		'32bitInt':2147483648,
+		'32bitFloat':1
+	}
+
+	return encodings[this.option.encoding]?encodings[this.option.encoding]:encodings['16bitInt'];
+};
+
+PCMPlayer.prototype.getTypedArray=function()
+{
+	var typedArrays={
+		'8bitInt': Int8Array,
+		'16bitInt':Int16Array,
+		'32bitInt':Int32Array,
+		'32bitFloat':Float32Array
+	}
+
+	return typedArrays[this.option.encoding]?typedArrays[this.option.encoding]:typedArrays['16bitInt'];
+};
+
+PCMPlayer.prototype.createContext=function()
+{
+	this.audioCtx=new (window.AudioContext||window.webkitAudioContext)();
+	this.gainNode=this.audioCtx.createGain();
+	this.gainNode.gain.value=1;
+	this.gainNode.connect(this.audioCtx.destination);
+	this.startTime=this.audioCtx.currentTime;
+};
+
+PCMPlayer.prototype.isTypedArray=function(data)
+{
+	return (data.byteLength&&data.buffer&&data.buffer.constructor==ArrayBuffer);
+};
+
+PCMPlayer.prototype.feed=function(data)
+{
+	if(!this.isTypedArray(data)) return;
+	data=this.getFormatedValue(data);
+	var tmp=new Float32Array(this.samples.length+data.length);
+	tmp.set(this.samples,0);
+	tmp.set(data,this.samples.length);
+	this.samples=tmp;
+};
+
+PCMPlayer.prototype.getFormatedValue=function(data)
+{
+	var data=new this.typedArray(data.buffer),
+		float32=new Float32Array(data.length),
+		i;
+
+	for(i=0; i<data.length; i++)
+	{
+		float32[i]=data[i]/this.maxValue;
+	}
+	return float32;
+};
+
+PCMPlayer.prototype.volume=function(volume)
+{
+	this.gainNode.gain.value=volume;
+};
+
+PCMPlayer.prototype.destroy=function()
+{
+	if(this.interval)
+	{
+		clearInterval(this.interval);
+	}
+	this.samples=null;
+	this.audioCtx.close();
+	this.audioCtx=null;
+};
+
+PCMPlayer.prototype.flush=function()
+{
+	if(!this.samples.length) return;
+	var bufferSource=this.audioCtx.createBufferSource(),
+		length=this.samples.length/this.option.channels,
+		audioBuffer=this.audioCtx.createBuffer(this.option.channels,length,this.option.sampleRate),
+		audioData,
+		channel,
+		offset,
+		i,
+		decrement;
+
+	for(channel=0; channel<this.option.channels; channel++)
+	{
+		audioData=audioBuffer.getChannelData(channel);
+		offset=channel;
+		decrement=50;
+		for(i=0; i<length; i++)
+		{
+			audioData[i]=this.samples[offset];
+			/* fadein */
+			if(i<50)
+			{
+				audioData[i]=(audioData[i]*i)/50;
+			}
+			/* fadeout*/
+			if(i>=(length-51))
+			{
+				audioData[i]=(audioData[i]*decrement--)/50;
+			}
+			offset+=this.option.channels;
+		}
+	}
+
+	if(this.startTime<this.audioCtx.currentTime)
+	{
+		this.startTime=this.audioCtx.currentTime;
+	}
+	//console.log('start vs current '+this.startTime+' vs '+this.audioCtx.currentTime+' duration: '+audioBuffer.duration);
+	bufferSource.buffer=audioBuffer;
+	bufferSource.connect(this.gainNode);
+	bufferSource.start(this.startTime);
+	this.startTime+=audioBuffer.duration;
+	this.samples=new Float32Array();
+};
+
+PCMPlayer.prototype.getTimestamp=function()
+{
+	if(this.audioCtx)
+	{
+		return this.audioCtx.currentTime;
+	}
+	else
+	{
+		return 0;
+	}
+};
+
+PCMPlayer.prototype.play=function(data)
+{
+	if(!this.isTypedArray(data))
+	{
+		return;
+	}
+
+	data=this.getFormatedValue(data);
+	if(!data.length)
+	{
+		return;
+	}
+
+	var bufferSource=this.audioCtx.createBufferSource(),
+		length=data.length/this.option.channels,
+		audioBuffer=this.audioCtx.createBuffer(this.option.channels,length,this.option.sampleRate),
+		audioData,
+		channel,
+		offset,
+		i,
+		decrement;
+
+	for(channel=0; channel<this.option.channels; channel++)
+	{
+		audioData=audioBuffer.getChannelData(channel);
+		offset=channel;
+		decrement=50;
+		for(i=0; i<length; i++)
+		{
+			audioData[i]=data[offset];
+			/* fadein */
+			if(i<50)
+			{
+				audioData[i]=(audioData[i]*i)/50;
+			}
+			/* fadeout*/
+			if(i>=(length-51))
+			{
+				audioData[i]=(audioData[i]*decrement--)/50;
+			}
+			offset+=this.option.channels;
+		}
+	}
+
+	if(this.startTime<this.audioCtx.currentTime)
+	{
+		this.startTime=this.audioCtx.currentTime;
+	}
+	//console.log('start vs current '+this.startTime+' vs '+this.audioCtx.currentTime+' duration: '+audioBuffer.duration);
+	bufferSource.buffer=audioBuffer;
+	bufferSource.connect(this.gainNode);
+	bufferSource.start(this.startTime);
+	this.startTime+=audioBuffer.duration;
+};
+
+PCMPlayer.prototype.pause=function()
+{
+	if(this.audioCtx.state==='running')
+	{
+		this.audioCtx.suspend()
+	}
+}
+
+PCMPlayer.prototype.resume=function()
+{
+	if(this.audioCtx.state==='suspended')
+	{
+		this.audioCtx.resume()
+	}
+}
\ No newline at end of file
diff --git a/src/components/wasmPlayer/wasm/player.js b/src/components/wasmPlayer/wasm/player.js
new file mode 100644
index 0000000..4ac8f26
--- /dev/null
+++ b/src/components/wasmPlayer/wasm/player.js
@@ -0,0 +1,182 @@
+import { PCMPlayer } from './pcm-player'
+import { WebGLPlayer } from './webgl'
+
+export function Player() {
+  this.hPlayer = 0
+  this.PlayOrPause = 0
+  this.MediaName = null
+  this.isStream = false
+  this.canvas = null
+  this.timeLabel = null
+  this.timeTrack = null
+  this.CurPos = 0
+  this.displayDuration = '00:00:00'
+
+  this.pcmPlayer = null
+  this.webglPlayer = null
+
+  this.trackTimer = null
+}
+
+Player.prototype.play = function(
+  url,
+  canvas,
+  isStream,
+  timeTrack,
+  timeLabel,
+  payload
+) {
+  if (this.hPlayer != 0) return
+
+  this.MediaName = url
+
+  this.isStream = isStream
+
+  this.canvas = canvas //hWnd
+
+  this.timeTrack = timeTrack
+  this.timeLabel = timeLabel
+
+  var This = this
+  this.timeTrack.oninput = function() {
+    This.seek(This.timeTrack.value)
+  }
+  this.timeTrack.onchange = function() {
+    This.seek(This.timeTrack.value)
+  }
+
+  this.TurboWorker = new Worker('/libs/wasmPlayer/turbo.js')
+  this.hPlayer = 1
+  this.PlayOrPause = 1
+
+  this.TurboWorker.onmessage = function(evt) {
+    switch (evt.data.command) {
+      case 'initialized': {
+        This.TurboWorker.postMessage({
+          command: 'play',
+          media_name: url,
+          other: isStream,
+          payload: payload,
+        })
+        break
+      }
+      case 'create_video': {
+        This.VideoParam = evt.data.param //{duration:xxx,width:xxx,height:xxx}
+        This.webglPlayer = new WebGLPlayer(This.canvas)
+        if (This.timeTrack) {
+          This.timeTrack.min = 0
+          This.timeTrack.max = This.VideoParam.duration
+          This.timeTrack.value = 0
+          This.displayDuration = This.formatTime(
+            This.VideoParam.duration / 1000
+          )
+        }
+        This.startTrackTimer()
+        break
+      }
+      case 'create_audio': {
+        This.AudioParam = evt.data.param //{channel:Channel,sample_rate:SampleRate}
+        This.pcmPlayer = new PCMPlayer({
+          encoding: '16bitInt',
+          channels: This.AudioParam.channel,
+          sampleRate: This.AudioParam.sample_rate,
+          flushingTime: 5000,
+        })
+        break
+      }
+      case 'deliver_video': {
+        //sample:{time_stamp:xxx,data:xxx}
+        This.CurPos = evt.data.sample.time_stamp
+        This.webglPlayer.renderFrame(
+          evt.data.sample.buf,
+          This.VideoParam.width,
+          This.VideoParam.height
+        )
+        break
+      }
+      case 'deliver_audio': {
+        //sample:{time_stamp:xxx,data:xxx}
+        This.pcmPlayer.play(evt.data.sample.buf)
+        break
+      }
+      default:
+        return
+    }
+  }
+}
+
+Player.prototype.pause = function() {
+  if (this.hPlayer == 0 || this.PlayOrPause == 0) return
+  this.PlayOrPause = 0
+  this.TurboWorker.postMessage({ command: 'pause' })
+}
+
+Player.prototype.resume = function() {
+  if (this.hPlayer == 0 || this.PlayOrPause == 1) return
+  this.PlayOrPause = 1
+  this.TurboWorker.postMessage({ command: 'resume' })
+}
+
+Player.prototype.stop = function() {
+  if (this.hPlayer == 0) return
+  this.hPlayer = 0
+  this.TurboWorker.postMessage({ command: 'stop' })
+  this.stopTrackTimer()
+  if (this.pcmPlayer) {
+    this.pcmPlayer.destroy()
+    this.pcmPlayer = null
+  }
+  //webglPlayer?
+}
+
+Player.prototype.seek = function(ms) {
+  if (this.hPlayer == 0) return
+  this.TurboWorker.postMessage({ command: 'seek', pos: ms })
+
+  if (this.pcmPlayer != null) {
+    this.pcmPlayer.destroy()
+    this.pcmPlayer = new PCMPlayer({
+      encoding: '16bitInt',
+      channels: this.AudioParam.channel,
+      sampleRate: this.AudioParam.sample_rate,
+      flushingTime: 5000,
+    })
+  }
+}
+
+Player.prototype.fullscreen = function() {
+  if (this.webglPlayer) this.webglPlayer.fullscreen()
+}
+
+Player.prototype.startTrackTimer = function() {
+  var This = this
+  this.trackTimer = setInterval(function() {
+    if (This.timeTrack) This.timeTrack.value = This.CurPos
+
+    if (This.timeLabel)
+      This.timeLabel.innerHTML =
+        This.formatTime(This.CurPos / 1000) + '/' + This.displayDuration
+  }, 500)
+}
+
+Player.prototype.stopTrackTimer = function() {
+  if (this.trackTimer != null) {
+    clearInterval(this.trackTimer)
+    this.trackTimer = null
+  }
+}
+
+Player.prototype.formatTime = function(s) {
+  var h =
+    Math.floor(s / 3600) < 10
+      ? '0' + Math.floor(s / 3600)
+      : Math.floor(s / 3600)
+  var m =
+    Math.floor((s / 60) % 60) < 10
+      ? '0' + Math.floor((s / 60) % 60)
+      : Math.floor((s / 60) % 60)
+  var s =
+    Math.floor(s % 60) < 10 ? '0' + Math.floor(s % 60) : Math.floor(s % 60)
+
+  return h + ':' + m + ':' + s
+}
diff --git a/src/components/wasmPlayer/wasm/webgl.js b/src/components/wasmPlayer/wasm/webgl.js
new file mode 100644
index 0000000..7d2c0cf
--- /dev/null
+++ b/src/components/wasmPlayer/wasm/webgl.js
@@ -0,0 +1,188 @@
+function Texture(gl) {
+  this.gl = gl
+  this.texture = gl.createTexture()
+  gl.bindTexture(gl.TEXTURE_2D, this.texture)
+
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
+
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
+  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
+}
+
+Texture.prototype.bind = function(n, program, name) {
+  var gl = this.gl
+  gl.activeTexture([gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2][n])
+  gl.bindTexture(gl.TEXTURE_2D, this.texture)
+  gl.uniform1i(gl.getUniformLocation(program, name), n)
+}
+
+Texture.prototype.fill = function(width, height, data) {
+  var gl = this.gl
+  gl.bindTexture(gl.TEXTURE_2D, this.texture)
+  gl.texImage2D(
+    gl.TEXTURE_2D,
+    0,
+    gl.LUMINANCE,
+    width,
+    height,
+    0,
+    gl.LUMINANCE,
+    gl.UNSIGNED_BYTE,
+    data
+  )
+}
+
+export function WebGLPlayer(canvas) {
+  this.canvas = canvas
+  this.gl =
+    canvas.getContext('webgl') || canvas.getContext('experimental-webgl')
+  this.initGL()
+}
+
+WebGLPlayer.prototype.initGL = function() {
+  if (!this.gl) {
+    console.log('[ER] WebGL not supported.')
+    return
+  }
+
+  var gl = this.gl
+  gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1)
+  var program = gl.createProgram()
+  var vertexShaderSource = [
+    'attribute highp vec4 aVertexPosition;',
+    'attribute vec2 aTextureCoord;',
+    'varying highp vec2 vTextureCoord;',
+    'void main(void) {',
+    ' gl_Position = aVertexPosition;',
+    ' vTextureCoord = aTextureCoord;',
+    '}',
+  ].join('\n')
+  var vertexShader = gl.createShader(gl.VERTEX_SHADER)
+  gl.shaderSource(vertexShader, vertexShaderSource)
+  gl.compileShader(vertexShader)
+  var fragmentShaderSource = [
+    'precision highp float;',
+    'varying lowp vec2 vTextureCoord;',
+    'uniform sampler2D YTexture;',
+    'uniform sampler2D UTexture;',
+    'uniform sampler2D VTexture;',
+    'const mat4 YUV2RGB = mat4',
+    '(',
+    ' 1.1643828125, 0, 1.59602734375, -.87078515625,',
+    ' 1.1643828125, -.39176171875, -.81296875, .52959375,',
+    ' 1.1643828125, 2.017234375, 0, -1.081390625,',
+    ' 0, 0, 0, 1',
+    ');',
+    'void main(void) {',
+    ' gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB;',
+    '}',
+  ].join('\n')
+
+  var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
+  gl.shaderSource(fragmentShader, fragmentShaderSource)
+  gl.compileShader(fragmentShader)
+  gl.attachShader(program, vertexShader)
+  gl.attachShader(program, fragmentShader)
+  gl.linkProgram(program)
+  gl.useProgram(program)
+  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
+    console.log('[ER] Shader link failed.')
+  }
+  var vertexPositionAttribute = gl.getAttribLocation(program, 'aVertexPosition')
+  gl.enableVertexAttribArray(vertexPositionAttribute)
+  var textureCoordAttribute = gl.getAttribLocation(program, 'aTextureCoord')
+  gl.enableVertexAttribArray(textureCoordAttribute)
+
+  var verticesBuffer = gl.createBuffer()
+  gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer)
+  gl.bufferData(
+    gl.ARRAY_BUFFER,
+    new Float32Array([
+      1.0,
+      1.0,
+      0.0,
+      -1.0,
+      1.0,
+      0.0,
+      1.0,
+      -1.0,
+      0.0,
+      -1.0,
+      -1.0,
+      0.0,
+    ]),
+    gl.STATIC_DRAW
+  )
+  gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0)
+  var texCoordBuffer = gl.createBuffer()
+  gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer)
+  gl.bufferData(
+    gl.ARRAY_BUFFER,
+    new Float32Array([1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0]),
+    gl.STATIC_DRAW
+  )
+  gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0)
+
+  gl.y = new Texture(gl)
+  gl.u = new Texture(gl)
+  gl.v = new Texture(gl)
+  gl.y.bind(0, program, 'YTexture')
+  gl.u.bind(1, program, 'UTexture')
+  gl.v.bind(2, program, 'VTexture')
+}
+
+WebGLPlayer.prototype.renderFrame = function(videoFrame, width, height) {
+  if (!this.gl) {
+    console.log('[ER] Render frame failed due to WebGL not supported.')
+    return
+  }
+
+  var gl = this.gl
+  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)
+  gl.clearColor(0.0, 0.0, 0.0, 0.0)
+  gl.clear(gl.COLOR_BUFFER_BIT)
+
+  gl.y.fill(width, height, videoFrame.subarray(0, width * height))
+  gl.u.fill(
+    width >> 1,
+    height >> 1,
+    videoFrame.subarray(width * height, (width * height * 5) / 4)
+  )
+  gl.v.fill(
+    width >> 1,
+    height >> 1,
+    videoFrame.subarray((width * height * 5) / 4, (width * height * 3) / 2)
+  )
+
+  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)
+}
+
+WebGLPlayer.prototype.fullscreen = function() {
+  var canvas = this.canvas
+  if (canvas.RequestFullScreen) {
+    canvas.RequestFullScreen()
+  } else if (canvas.webkitRequestFullScreen) {
+    canvas.webkitRequestFullScreen()
+  } else if (canvas.mozRequestFullScreen) {
+    canvas.mozRequestFullScreen()
+  } else if (canvas.msRequestFullscreen) {
+    canvas.msRequestFullscreen()
+  } else {
+    alert("This browser doesn't supporter fullscreen")
+  }
+}
+
+WebGLPlayer.prototype.exitfullscreen = function() {
+  if (document.exitFullscreen) {
+    document.exitFullscreen()
+  } else if (document.webkitExitFullscreen) {
+    document.webkitExitFullscreen()
+  } else if (document.mozCancelFullScreen) {
+    document.mozCancelFullScreen()
+  } else if (document.msExitFullscreen) {
+    document.msExitFullscreen()
+  } else {
+    alert("Exit fullscreen doesn't work")
+  }
+}
diff --git a/src/pages/cameraVideo/components/VideoItem.vue b/src/pages/cameraVideo/components/VideoItem.vue
index 58211b9..f374d94 100644
--- a/src/pages/cameraVideo/components/VideoItem.vue
+++ b/src/pages/cameraVideo/components/VideoItem.vue
@@ -28,7 +28,8 @@
         <p class="p3" @mousedown="ptCtrl('down')" @mouseup="ptStop"></p>
         <p class="p4" @mousedown="ptCtrl('left')" @mouseup="ptStop"></p>
       </div>
-      <camera-player
+
+      <!-- <camera-player
         :cameraName="videoItem.name"
         :cameraID="videoItem.id"
         :rtspUrl="videoItem.rtsp"
@@ -36,15 +37,18 @@
         :isGb="videoItem.cameraType === 1"
         :showArea="showArea"
         v-if="videoItem !== '' && videoItem !== undefined && videoItem !== null && TreeDataPool.treeActiveName==='camera'"
-      ></camera-player>
+      ></camera-player> -->
 
-      <video
-        v-if="videoItem !== '' && videoItem !== undefined && videoItem !== null && TreeDataPool.treeActiveName==='dataStack'"
-        :src="videoItem.rtsp"
-        autoplay="autoplay"
-        poster="/images/cameraVideo/video-poster.png"
-        controls
-      >鎮ㄧ殑娴忚鍣ㄤ笉鏀寔 video 鏍囩銆�</video>
+      <wasm-player
+        :cameraName="videoItem.name"
+        :cameraID="videoItem.id"
+        :rtspUrl="videoItem.rtsp"
+        :isRunning="videoItem.isRunning"
+        :isGb="videoItem.cameraType === 1"
+        :showArea="showArea"
+        v-if="videoItem !== '' && videoItem !== undefined && videoItem !== null && TreeDataPool.treeActiveName==='camera'"
+      ></wasm-player>
+
     </div>
   </div>
 </template>
@@ -53,10 +57,12 @@
 import { ptzControl } from "@/api/camera"
 
 import CameraPlayer from "@/components/player";
+import WasmPlayer from "@/components/wasmPlayer";
 
 export default {
   components: {
-    CameraPlayer
+    // CameraPlayer,
+    WasmPlayer
   },
   props: {
     videoGuid: {

--
Gitblit v1.8.0